blob: d6b516fd5cf4b067b08f635fb31d74c33f0c3da9 [file] [log] [blame]
John Reck04fc5832014-02-05 16:38:25 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "DeferredLayerUpdater.h"
17
Fedor Kudasovd501e102019-06-21 10:22:53 +010018#include <GLES2/gl2.h>
19#include <GLES2/gl2ext.h>
20
Stan Ilievaaa9e832019-09-17 14:07:23 -040021#include "AutoBackendTextureRelease.h"
22#include "Matrix.h"
23#include "Properties.h"
sergeyv3e9999b2017-01-19 15:37:02 -080024#include "renderstate/RenderState.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040025#include "renderthread/EglManager.h"
26#include "renderthread/RenderThread.h"
27#include "renderthread/VulkanManager.h"
28
29using namespace android::uirenderer::renderthread;
John Reck04fc5832014-02-05 16:38:25 -080030
31namespace android {
32namespace uirenderer {
33
Stan Iliev564ca3e2018-09-04 22:00:00 +000034DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState)
sergeyv3e9999b2017-01-19 15:37:02 -080035 : mRenderState(renderState)
36 , mBlend(false)
Chris Craikd41c4d82015-01-05 15:51:13 -080037 , mTransform(nullptr)
sergeyv00eb43d2017-02-13 14:34:15 -080038 , mGLContextAttached(false)
John Reck04fc5832014-02-05 16:38:25 -080039 , mUpdateTexImage(false)
Stan Iliev564ca3e2018-09-04 22:00:00 +000040 , mLayer(nullptr) {
Derek Sollenberger28a4d992018-09-20 13:37:24 -040041 renderState.registerContextCallback(this);
John Reck04fc5832014-02-05 16:38:25 -080042}
43
44DeferredLayerUpdater::~DeferredLayerUpdater() {
Chris Craikd41c4d82015-01-05 15:51:13 -080045 setTransform(nullptr);
Derek Sollenberger28a4d992018-09-20 13:37:24 -040046 mRenderState.removeContextCallback(this);
47 destroyLayer();
48}
49
Stan Ilievaaa9e832019-09-17 14:07:23 -040050void DeferredLayerUpdater::setSurfaceTexture(AutoTextureRelease&& consumer) {
51 mSurfaceTexture = std::move(consumer);
Fedor Kudasovd501e102019-06-21 10:22:53 +010052
Stan Ilievaaa9e832019-09-17 14:07:23 -040053 GLenum target = ASurfaceTexture_getCurrentTextureTarget(mSurfaceTexture.get());
54 LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
55 "set unsupported SurfaceTexture with target %x", target);
Fedor Kudasovd501e102019-06-21 10:22:53 +010056}
57
Derek Sollenberger28a4d992018-09-20 13:37:24 -040058void DeferredLayerUpdater::onContextDestroyed() {
sergeyv3e9999b2017-01-19 15:37:02 -080059 destroyLayer();
60}
61
62void DeferredLayerUpdater::destroyLayer() {
sergeyv00eb43d2017-02-13 14:34:15 -080063 if (!mLayer) {
64 return;
sergeyv3e9999b2017-01-19 15:37:02 -080065 }
sergeyv00eb43d2017-02-13 14:34:15 -080066
Stan Iliev564ca3e2018-09-04 22:00:00 +000067 if (mSurfaceTexture.get() && mGLContextAttached) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040068 ASurfaceTexture_releaseConsumerOwnership(mSurfaceTexture.get());
sergeyv00eb43d2017-02-13 14:34:15 -080069 mGLContextAttached = false;
sergeyv00eb43d2017-02-13 14:34:15 -080070 }
71
72 mLayer->postDecStrong();
Stan Iliev1a025a72018-09-05 16:35:11 -040073
sergeyv00eb43d2017-02-13 14:34:15 -080074 mLayer = nullptr;
Stan Ilievaaa9e832019-09-17 14:07:23 -040075
76 mImageSlots.clear();
John Reck04fc5832014-02-05 16:38:25 -080077}
78
Derek Sollenberger674554f2014-02-19 16:47:32 +000079void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
Chris Craikbf6f0f22015-10-01 12:36:07 -070080 mAlpha = PaintUtils::getAlphaDirect(paint);
Mike Reed260ab722016-10-07 15:59:20 -040081 mMode = PaintUtils::getBlendModeDirect(paint);
Derek Sollenbergerbe3876c2018-04-20 16:13:31 -040082 if (paint) {
83 mColorFilter = paint->refColorFilter();
84 } else {
85 mColorFilter.reset();
86 }
John Reck04fc5832014-02-05 16:38:25 -080087}
88
Stan Ilievaaa9e832019-09-17 14:07:23 -040089static status_t createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, EGLDisplay* display,
90 int* releaseFence, void* handle) {
91 *display = EGL_NO_DISPLAY;
92 RenderState* renderState = (RenderState*)handle;
93 status_t err;
94 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
95 EglManager& eglManager = renderState->getRenderThread().eglManager();
96 *display = eglManager.eglDisplay();
97 err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
98 } else {
99 err = renderState->getRenderThread().vulkanManager().createReleaseFence(
100 releaseFence, renderState->getRenderThread().getGrContext());
101 }
102 return err;
103}
104
105static status_t fenceWait(int fence, void* handle) {
106 // Wait on the producer fence for the buffer to be ready.
107 status_t err;
108 RenderState* renderState = (RenderState*)handle;
109 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
110 err = renderState->getRenderThread().eglManager().fenceWait(fence);
111 } else {
112 err = renderState->getRenderThread().vulkanManager().fenceWait(
113 fence, renderState->getRenderThread().getGrContext());
114 }
115 return err;
116}
117
Chris Craikd2dfd8f2015-12-16 14:27:20 -0800118void DeferredLayerUpdater::apply() {
sergeyv3e9999b2017-01-19 15:37:02 -0800119 if (!mLayer) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000120 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode);
sergeyv3e9999b2017-01-19 15:37:02 -0800121 }
122
John Reck04fc5832014-02-05 16:38:25 -0800123 mLayer->setColorFilter(mColorFilter);
124 mLayer->setAlpha(mAlpha, mMode);
125
John Reck25fbb3f2014-06-12 13:46:45 -0700126 if (mSurfaceTexture.get()) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000127 if (!mGLContextAttached) {
128 mGLContextAttached = true;
129 mUpdateTexImage = true;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400130 ASurfaceTexture_takeConsumerOwnership(mSurfaceTexture.get());
Stan Iliev85f90962018-08-31 18:35:06 +0000131 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000132 if (mUpdateTexImage) {
133 mUpdateTexImage = false;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400134 float transformMatrix[16];
135 android_dataspace dataspace;
136 int slot;
137 bool newContent = false;
138 // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
139 // is necessary if the SurfaceTexture queue is in synchronous mode, and we
140 // cannot tell which mode it is in.
141 AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
142 mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &newContent,
143 createReleaseFence, fenceWait, &mRenderState);
144
145 if (hardwareBuffer) {
146 sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
147 hardwareBuffer, dataspace, newContent,
148 mRenderState.getRenderThread().getGrContext());
149 if (layerImage.get()) {
150 SkMatrix textureTransform;
151 mat4(transformMatrix).copyTo(textureTransform);
152 // force filtration if buffer size != layer size
153 bool forceFilter =
154 mWidth != layerImage->width() || mHeight != layerImage->height();
155 updateLayer(forceFilter, textureTransform, layerImage);
156 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000157 }
158 }
159
John Reck04fc5832014-02-05 16:38:25 -0800160 if (mTransform) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000161 mLayer->getTransform() = *mTransform;
Chris Craikd41c4d82015-01-05 15:51:13 -0800162 setTransform(nullptr);
John Reck04fc5832014-02-05 16:38:25 -0800163 }
164 }
John Reck04fc5832014-02-05 16:38:25 -0800165}
166
Stan Iliev564ca3e2018-09-04 22:00:00 +0000167void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform,
Stan Ilievaaa9e832019-09-17 14:07:23 -0400168 const sk_sp<SkImage>& layerImage) {
Greg Daniel45ec62b2017-01-04 14:27:00 -0500169 mLayer->setBlend(mBlend);
170 mLayer->setForceFilter(forceFilter);
171 mLayer->setSize(mWidth, mHeight);
Stan Iliev564ca3e2018-09-04 22:00:00 +0000172 mLayer->getTexTransform() = textureTransform;
Stan Iliev564ca3e2018-09-04 22:00:00 +0000173 mLayer->setImage(layerImage);
Greg Daniel45ec62b2017-01-04 14:27:00 -0500174}
175
John Reck918ad522014-06-27 14:45:25 -0700176void DeferredLayerUpdater::detachSurfaceTexture() {
177 if (mSurfaceTexture.get()) {
sergeyv00eb43d2017-02-13 14:34:15 -0800178 destroyLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800179 mSurfaceTexture = nullptr;
John Reck918ad522014-06-27 14:45:25 -0700180 }
181}
182
Stan Ilievaaa9e832019-09-17 14:07:23 -0400183sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
184 android_dataspace dataspace,
185 bool forceCreate,
186 GrContext* context) {
187 if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
188 forceCreate || mBuffer != buffer) {
189 if (buffer != mBuffer) {
190 clear();
191 }
192
193 if (!buffer) {
194 return nullptr;
195 }
196
197 if (!mTextureRelease) {
198 mTextureRelease = new AutoBackendTextureRelease(context, buffer);
199 } else {
200 mTextureRelease->newBufferContent(context);
201 }
202
203 mDataspace = dataspace;
204 mBuffer = buffer;
205 mTextureRelease->makeImage(buffer, dataspace, context);
206 }
207 return mTextureRelease ? mTextureRelease->getImage() : nullptr;
208}
209
210void DeferredLayerUpdater::ImageSlot::clear() {
211 if (mTextureRelease) {
212 // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
213 mTextureRelease->unref(true);
214 mTextureRelease = nullptr;
215 }
216
217 mBuffer = nullptr;
218}
219
John Reck04fc5832014-02-05 16:38:25 -0800220} /* namespace uirenderer */
221} /* namespace android */