blob: 6cb53206f60b9389c4d8e35d2d9b1b640f2a30f6 [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 Iliev5af5d302020-01-13 11:29:18 -050021// TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead.
22#include <surfacetexture/surface_texture_platform.h>
Stan Ilievaaa9e832019-09-17 14:07:23 -040023#include "AutoBackendTextureRelease.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040024#include "Properties.h"
sergeyv3e9999b2017-01-19 15:37:02 -080025#include "renderstate/RenderState.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040026#include "renderthread/EglManager.h"
27#include "renderthread/RenderThread.h"
28#include "renderthread/VulkanManager.h"
29
30using namespace android::uirenderer::renderthread;
John Reck04fc5832014-02-05 16:38:25 -080031
32namespace android {
33namespace uirenderer {
34
Stan Iliev564ca3e2018-09-04 22:00:00 +000035DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState)
sergeyv3e9999b2017-01-19 15:37:02 -080036 : mRenderState(renderState)
37 , mBlend(false)
Stan Iliev5af5d302020-01-13 11:29:18 -050038 , mSurfaceTexture(nullptr, [](ASurfaceTexture*) {})
Chris Craikd41c4d82015-01-05 15:51:13 -080039 , mTransform(nullptr)
sergeyv00eb43d2017-02-13 14:34:15 -080040 , mGLContextAttached(false)
John Reck04fc5832014-02-05 16:38:25 -080041 , mUpdateTexImage(false)
Stan Iliev564ca3e2018-09-04 22:00:00 +000042 , mLayer(nullptr) {
Derek Sollenberger28a4d992018-09-20 13:37:24 -040043 renderState.registerContextCallback(this);
John Reck04fc5832014-02-05 16:38:25 -080044}
45
46DeferredLayerUpdater::~DeferredLayerUpdater() {
Chris Craikd41c4d82015-01-05 15:51:13 -080047 setTransform(nullptr);
Derek Sollenberger28a4d992018-09-20 13:37:24 -040048 mRenderState.removeContextCallback(this);
49 destroyLayer();
50}
51
Stan Ilievaaa9e832019-09-17 14:07:23 -040052void DeferredLayerUpdater::setSurfaceTexture(AutoTextureRelease&& consumer) {
53 mSurfaceTexture = std::move(consumer);
Fedor Kudasovd501e102019-06-21 10:22:53 +010054
Stan Ilievaaa9e832019-09-17 14:07:23 -040055 GLenum target = ASurfaceTexture_getCurrentTextureTarget(mSurfaceTexture.get());
56 LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
57 "set unsupported SurfaceTexture with target %x", target);
Fedor Kudasovd501e102019-06-21 10:22:53 +010058}
59
Derek Sollenberger28a4d992018-09-20 13:37:24 -040060void DeferredLayerUpdater::onContextDestroyed() {
sergeyv3e9999b2017-01-19 15:37:02 -080061 destroyLayer();
62}
63
64void DeferredLayerUpdater::destroyLayer() {
sergeyv00eb43d2017-02-13 14:34:15 -080065 if (!mLayer) {
66 return;
sergeyv3e9999b2017-01-19 15:37:02 -080067 }
sergeyv00eb43d2017-02-13 14:34:15 -080068
Stan Iliev564ca3e2018-09-04 22:00:00 +000069 if (mSurfaceTexture.get() && mGLContextAttached) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040070 ASurfaceTexture_releaseConsumerOwnership(mSurfaceTexture.get());
sergeyv00eb43d2017-02-13 14:34:15 -080071 mGLContextAttached = false;
sergeyv00eb43d2017-02-13 14:34:15 -080072 }
73
74 mLayer->postDecStrong();
Stan Iliev1a025a72018-09-05 16:35:11 -040075
sergeyv00eb43d2017-02-13 14:34:15 -080076 mLayer = nullptr;
Stan Ilievaaa9e832019-09-17 14:07:23 -040077
Greg Daniel27e1fa22021-05-26 09:24:15 -040078 for (auto& [index, slot] : mImageSlots) {
79 slot.clear(mRenderState.getRenderThread().getGrContext());
80 }
Stan Ilievaaa9e832019-09-17 14:07:23 -040081 mImageSlots.clear();
John Reck04fc5832014-02-05 16:38:25 -080082}
83
Derek Sollenberger674554f2014-02-19 16:47:32 +000084void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
Chris Craikbf6f0f22015-10-01 12:36:07 -070085 mAlpha = PaintUtils::getAlphaDirect(paint);
Mike Reed260ab722016-10-07 15:59:20 -040086 mMode = PaintUtils::getBlendModeDirect(paint);
Derek Sollenbergerbe3876c2018-04-20 16:13:31 -040087 if (paint) {
88 mColorFilter = paint->refColorFilter();
89 } else {
90 mColorFilter.reset();
91 }
John Reck04fc5832014-02-05 16:38:25 -080092}
93
Greg Daniel27e1fa22021-05-26 09:24:15 -040094status_t DeferredLayerUpdater::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
95 EGLDisplay* display, int* releaseFence,
96 void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040097 *display = EGL_NO_DISPLAY;
Greg Daniel27e1fa22021-05-26 09:24:15 -040098 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
99 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400100 status_t err;
101 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400102 EglManager& eglManager = renderState.getRenderThread().eglManager();
Stan Ilievaaa9e832019-09-17 14:07:23 -0400103 *display = eglManager.eglDisplay();
104 err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
105 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400106 int previousSlot = dlu->mCurrentSlot;
107 if (previousSlot != -1) {
108 dlu->mImageSlots[previousSlot].releaseQueueOwnership(
109 renderState.getRenderThread().getGrContext());
110 }
111 err = renderState.getRenderThread().vulkanManager().createReleaseFence(
112 releaseFence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400113 }
114 return err;
115}
116
Greg Daniel27e1fa22021-05-26 09:24:15 -0400117status_t DeferredLayerUpdater::fenceWait(int fence, void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400118 // Wait on the producer fence for the buffer to be ready.
119 status_t err;
Greg Daniel27e1fa22021-05-26 09:24:15 -0400120 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
121 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400122 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400123 err = renderState.getRenderThread().eglManager().fenceWait(fence);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400124 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400125 err = renderState.getRenderThread().vulkanManager().fenceWait(
126 fence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400127 }
128 return err;
129}
130
Chris Craikd2dfd8f2015-12-16 14:27:20 -0800131void DeferredLayerUpdater::apply() {
sergeyv3e9999b2017-01-19 15:37:02 -0800132 if (!mLayer) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000133 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode);
sergeyv3e9999b2017-01-19 15:37:02 -0800134 }
135
John Reck04fc5832014-02-05 16:38:25 -0800136 mLayer->setColorFilter(mColorFilter);
137 mLayer->setAlpha(mAlpha, mMode);
138
John Reck25fbb3f2014-06-12 13:46:45 -0700139 if (mSurfaceTexture.get()) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000140 if (!mGLContextAttached) {
141 mGLContextAttached = true;
142 mUpdateTexImage = true;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400143 ASurfaceTexture_takeConsumerOwnership(mSurfaceTexture.get());
Stan Iliev85f90962018-08-31 18:35:06 +0000144 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000145 if (mUpdateTexImage) {
146 mUpdateTexImage = false;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400147 android_dataspace dataspace;
148 int slot;
149 bool newContent = false;
ramindanief54c032021-07-16 22:33:25 +0000150 ARect rect;
151 uint32_t textureTransform;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400152 // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
153 // is necessary if the SurfaceTexture queue is in synchronous mode, and we
154 // cannot tell which mode it is in.
155 AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
ramindanief54c032021-07-16 22:33:25 +0000156 mSurfaceTexture.get(), &slot, &dataspace, &newContent, createReleaseFence,
157 fenceWait, this, &rect, &textureTransform);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400158
159 if (hardwareBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400160 mCurrentSlot = slot;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400161 sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
162 hardwareBuffer, dataspace, newContent,
163 mRenderState.getRenderThread().getGrContext());
Stan Ilievd125b442020-07-16 17:03:27 -0400164 // unref to match the ref added by ASurfaceTexture_dequeueBuffer. eglCreateImageKHR
165 // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer.
166 AHardwareBuffer_release(hardwareBuffer);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400167 if (layerImage.get()) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400168 // force filtration if buffer size != layer size
169 bool forceFilter =
170 mWidth != layerImage->width() || mHeight != layerImage->height();
ramindanief54c032021-07-16 22:33:25 +0000171 SkRect cropRect =
172 SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom);
173 updateLayer(forceFilter, textureTransform, cropRect, layerImage);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400174 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000175 }
176 }
177
John Reck04fc5832014-02-05 16:38:25 -0800178 if (mTransform) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000179 mLayer->getTransform() = *mTransform;
Chris Craikd41c4d82015-01-05 15:51:13 -0800180 setTransform(nullptr);
John Reck04fc5832014-02-05 16:38:25 -0800181 }
182 }
John Reck04fc5832014-02-05 16:38:25 -0800183}
184
ramindanief54c032021-07-16 22:33:25 +0000185void DeferredLayerUpdater::updateLayer(bool forceFilter, const uint32_t textureTransform,
186 const SkRect cropRect, const sk_sp<SkImage>& layerImage) {
Greg Daniel45ec62b2017-01-04 14:27:00 -0500187 mLayer->setBlend(mBlend);
188 mLayer->setForceFilter(forceFilter);
189 mLayer->setSize(mWidth, mHeight);
ramindanief54c032021-07-16 22:33:25 +0000190 mLayer->setTextureTransform(textureTransform);
191 mLayer->setCropRect(cropRect);
Stan Iliev564ca3e2018-09-04 22:00:00 +0000192 mLayer->setImage(layerImage);
Greg Daniel45ec62b2017-01-04 14:27:00 -0500193}
194
John Reck918ad522014-06-27 14:45:25 -0700195void DeferredLayerUpdater::detachSurfaceTexture() {
196 if (mSurfaceTexture.get()) {
sergeyv00eb43d2017-02-13 14:34:15 -0800197 destroyLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800198 mSurfaceTexture = nullptr;
John Reck918ad522014-06-27 14:45:25 -0700199 }
200}
201
Stan Ilievaaa9e832019-09-17 14:07:23 -0400202sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
203 android_dataspace dataspace,
204 bool forceCreate,
Adlai Hollerf8c434e2020-07-27 11:42:45 -0400205 GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400206 if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
207 forceCreate || mBuffer != buffer) {
208 if (buffer != mBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400209 clear(context);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400210 }
211
212 if (!buffer) {
213 return nullptr;
214 }
215
216 if (!mTextureRelease) {
217 mTextureRelease = new AutoBackendTextureRelease(context, buffer);
218 } else {
219 mTextureRelease->newBufferContent(context);
220 }
221
222 mDataspace = dataspace;
223 mBuffer = buffer;
224 mTextureRelease->makeImage(buffer, dataspace, context);
225 }
226 return mTextureRelease ? mTextureRelease->getImage() : nullptr;
227}
228
Greg Daniel27e1fa22021-05-26 09:24:15 -0400229void DeferredLayerUpdater::ImageSlot::clear(GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400230 if (mTextureRelease) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400231 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
232 this->releaseQueueOwnership(context);
233 }
Stan Ilievaaa9e832019-09-17 14:07:23 -0400234 // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
235 mTextureRelease->unref(true);
236 mTextureRelease = nullptr;
237 }
238
239 mBuffer = nullptr;
240}
241
Greg Daniel27e1fa22021-05-26 09:24:15 -0400242void DeferredLayerUpdater::ImageSlot::releaseQueueOwnership(GrDirectContext* context) {
243 LOG_ALWAYS_FATAL_IF(Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan);
244 if (mTextureRelease) {
245 mTextureRelease->releaseQueueOwnership(context);
246 }
247}
248
John Reck04fc5832014-02-05 16:38:25 -0800249} /* namespace uirenderer */
250} /* namespace android */