blob: 0b3b39397ee41ab7a4388716596457317d85d8dc [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"
bsears9df09ccf2021-08-06 15:18:26 +000024#include "Matrix.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040025#include "Properties.h"
sergeyv3e9999b2017-01-19 15:37:02 -080026#include "renderstate/RenderState.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040027#include "renderthread/EglManager.h"
28#include "renderthread/RenderThread.h"
29#include "renderthread/VulkanManager.h"
30
31using namespace android::uirenderer::renderthread;
John Reck04fc5832014-02-05 16:38:25 -080032
33namespace android {
34namespace uirenderer {
35
Stan Iliev564ca3e2018-09-04 22:00:00 +000036DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState)
sergeyv3e9999b2017-01-19 15:37:02 -080037 : mRenderState(renderState)
38 , mBlend(false)
Stan Iliev5af5d302020-01-13 11:29:18 -050039 , mSurfaceTexture(nullptr, [](ASurfaceTexture*) {})
Chris Craikd41c4d82015-01-05 15:51:13 -080040 , mTransform(nullptr)
sergeyv00eb43d2017-02-13 14:34:15 -080041 , mGLContextAttached(false)
John Reck04fc5832014-02-05 16:38:25 -080042 , mUpdateTexImage(false)
Stan Iliev564ca3e2018-09-04 22:00:00 +000043 , mLayer(nullptr) {
Derek Sollenberger28a4d992018-09-20 13:37:24 -040044 renderState.registerContextCallback(this);
John Reck04fc5832014-02-05 16:38:25 -080045}
46
47DeferredLayerUpdater::~DeferredLayerUpdater() {
Chris Craikd41c4d82015-01-05 15:51:13 -080048 setTransform(nullptr);
Derek Sollenberger28a4d992018-09-20 13:37:24 -040049 mRenderState.removeContextCallback(this);
50 destroyLayer();
51}
52
Stan Ilievaaa9e832019-09-17 14:07:23 -040053void DeferredLayerUpdater::setSurfaceTexture(AutoTextureRelease&& consumer) {
54 mSurfaceTexture = std::move(consumer);
Fedor Kudasovd501e102019-06-21 10:22:53 +010055
Stan Ilievaaa9e832019-09-17 14:07:23 -040056 GLenum target = ASurfaceTexture_getCurrentTextureTarget(mSurfaceTexture.get());
57 LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
58 "set unsupported SurfaceTexture with target %x", target);
Fedor Kudasovd501e102019-06-21 10:22:53 +010059}
60
Derek Sollenberger28a4d992018-09-20 13:37:24 -040061void DeferredLayerUpdater::onContextDestroyed() {
sergeyv3e9999b2017-01-19 15:37:02 -080062 destroyLayer();
63}
64
65void DeferredLayerUpdater::destroyLayer() {
sergeyv00eb43d2017-02-13 14:34:15 -080066 if (!mLayer) {
67 return;
sergeyv3e9999b2017-01-19 15:37:02 -080068 }
sergeyv00eb43d2017-02-13 14:34:15 -080069
Stan Iliev564ca3e2018-09-04 22:00:00 +000070 if (mSurfaceTexture.get() && mGLContextAttached) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040071 ASurfaceTexture_releaseConsumerOwnership(mSurfaceTexture.get());
sergeyv00eb43d2017-02-13 14:34:15 -080072 mGLContextAttached = false;
sergeyv00eb43d2017-02-13 14:34:15 -080073 }
74
75 mLayer->postDecStrong();
Stan Iliev1a025a72018-09-05 16:35:11 -040076
sergeyv00eb43d2017-02-13 14:34:15 -080077 mLayer = nullptr;
Stan Ilievaaa9e832019-09-17 14:07:23 -040078
Greg Daniel27e1fa22021-05-26 09:24:15 -040079 for (auto& [index, slot] : mImageSlots) {
80 slot.clear(mRenderState.getRenderThread().getGrContext());
81 }
Stan Ilievaaa9e832019-09-17 14:07:23 -040082 mImageSlots.clear();
John Reck04fc5832014-02-05 16:38:25 -080083}
84
Derek Sollenberger674554f2014-02-19 16:47:32 +000085void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
Chris Craikbf6f0f22015-10-01 12:36:07 -070086 mAlpha = PaintUtils::getAlphaDirect(paint);
Mike Reed260ab722016-10-07 15:59:20 -040087 mMode = PaintUtils::getBlendModeDirect(paint);
Derek Sollenbergerbe3876c2018-04-20 16:13:31 -040088 if (paint) {
89 mColorFilter = paint->refColorFilter();
90 } else {
91 mColorFilter.reset();
92 }
John Reck04fc5832014-02-05 16:38:25 -080093}
94
Greg Daniel27e1fa22021-05-26 09:24:15 -040095status_t DeferredLayerUpdater::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
96 EGLDisplay* display, int* releaseFence,
97 void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040098 *display = EGL_NO_DISPLAY;
Greg Daniel27e1fa22021-05-26 09:24:15 -040099 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
100 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400101 status_t err;
102 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400103 EglManager& eglManager = renderState.getRenderThread().eglManager();
Stan Ilievaaa9e832019-09-17 14:07:23 -0400104 *display = eglManager.eglDisplay();
105 err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
106 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400107 int previousSlot = dlu->mCurrentSlot;
108 if (previousSlot != -1) {
109 dlu->mImageSlots[previousSlot].releaseQueueOwnership(
110 renderState.getRenderThread().getGrContext());
111 }
112 err = renderState.getRenderThread().vulkanManager().createReleaseFence(
113 releaseFence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400114 }
115 return err;
116}
117
Greg Daniel27e1fa22021-05-26 09:24:15 -0400118status_t DeferredLayerUpdater::fenceWait(int fence, void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400119 // Wait on the producer fence for the buffer to be ready.
120 status_t err;
Greg Daniel27e1fa22021-05-26 09:24:15 -0400121 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
122 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400123 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400124 err = renderState.getRenderThread().eglManager().fenceWait(fence);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400125 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400126 err = renderState.getRenderThread().vulkanManager().fenceWait(
127 fence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400128 }
129 return err;
130}
131
Chris Craikd2dfd8f2015-12-16 14:27:20 -0800132void DeferredLayerUpdater::apply() {
sergeyv3e9999b2017-01-19 15:37:02 -0800133 if (!mLayer) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000134 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode);
sergeyv3e9999b2017-01-19 15:37:02 -0800135 }
136
John Reck04fc5832014-02-05 16:38:25 -0800137 mLayer->setColorFilter(mColorFilter);
138 mLayer->setAlpha(mAlpha, mMode);
139
John Reck25fbb3f2014-06-12 13:46:45 -0700140 if (mSurfaceTexture.get()) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000141 if (!mGLContextAttached) {
142 mGLContextAttached = true;
143 mUpdateTexImage = true;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400144 ASurfaceTexture_takeConsumerOwnership(mSurfaceTexture.get());
Stan Iliev85f90962018-08-31 18:35:06 +0000145 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000146 if (mUpdateTexImage) {
147 mUpdateTexImage = false;
bsears9df09ccf2021-08-06 15:18:26 +0000148 float transformMatrix[16];
Stan Ilievaaa9e832019-09-17 14:07:23 -0400149 android_dataspace dataspace;
150 int slot;
151 bool newContent = false;
ramindanibd4971b2021-08-06 22:38:45 +0000152 ARect currentCrop;
153 uint32_t outTransform;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400154 // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
155 // is necessary if the SurfaceTexture queue is in synchronous mode, and we
156 // cannot tell which mode it is in.
157 AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
ramindanibd4971b2021-08-06 22:38:45 +0000158 mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &outTransform,
159 &newContent, createReleaseFence, fenceWait, this, &currentCrop);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400160
161 if (hardwareBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400162 mCurrentSlot = slot;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400163 sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
164 hardwareBuffer, dataspace, newContent,
165 mRenderState.getRenderThread().getGrContext());
Stan Ilievd125b442020-07-16 17:03:27 -0400166 // unref to match the ref added by ASurfaceTexture_dequeueBuffer. eglCreateImageKHR
167 // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer.
168 AHardwareBuffer_release(hardwareBuffer);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400169 if (layerImage.get()) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400170 // force filtration if buffer size != layer size
171 bool forceFilter =
172 mWidth != layerImage->width() || mHeight != layerImage->height();
ramindani3952ed62021-08-12 15:55:12 +0000173 SkRect currentCropRect =
174 SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right,
175 currentCrop.bottom);
176 updateLayer(forceFilter, layerImage, outTransform, currentCropRect);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400177 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000178 }
179 }
180
John Reck04fc5832014-02-05 16:38:25 -0800181 if (mTransform) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000182 mLayer->getTransform() = *mTransform;
Chris Craikd41c4d82015-01-05 15:51:13 -0800183 setTransform(nullptr);
John Reck04fc5832014-02-05 16:38:25 -0800184 }
185 }
John Reck04fc5832014-02-05 16:38:25 -0800186}
187
ramindani3952ed62021-08-12 15:55:12 +0000188void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage,
189 const uint32_t transform, SkRect currentCrop) {
Greg Daniel45ec62b2017-01-04 14:27:00 -0500190 mLayer->setBlend(mBlend);
191 mLayer->setForceFilter(forceFilter);
192 mLayer->setSize(mWidth, mHeight);
ramindani3952ed62021-08-12 15:55:12 +0000193 mLayer->setCurrentCropRect(currentCrop);
194 mLayer->setWindowTransform(transform);
Stan Iliev564ca3e2018-09-04 22:00:00 +0000195 mLayer->setImage(layerImage);
Greg Daniel45ec62b2017-01-04 14:27:00 -0500196}
197
John Reck918ad522014-06-27 14:45:25 -0700198void DeferredLayerUpdater::detachSurfaceTexture() {
199 if (mSurfaceTexture.get()) {
sergeyv00eb43d2017-02-13 14:34:15 -0800200 destroyLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800201 mSurfaceTexture = nullptr;
John Reck918ad522014-06-27 14:45:25 -0700202 }
203}
204
Stan Ilievaaa9e832019-09-17 14:07:23 -0400205sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
206 android_dataspace dataspace,
207 bool forceCreate,
Adlai Hollerf8c434e2020-07-27 11:42:45 -0400208 GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400209 if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
210 forceCreate || mBuffer != buffer) {
211 if (buffer != mBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400212 clear(context);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400213 }
214
215 if (!buffer) {
216 return nullptr;
217 }
218
219 if (!mTextureRelease) {
220 mTextureRelease = new AutoBackendTextureRelease(context, buffer);
221 } else {
222 mTextureRelease->newBufferContent(context);
223 }
224
225 mDataspace = dataspace;
226 mBuffer = buffer;
227 mTextureRelease->makeImage(buffer, dataspace, context);
228 }
229 return mTextureRelease ? mTextureRelease->getImage() : nullptr;
230}
231
Greg Daniel27e1fa22021-05-26 09:24:15 -0400232void DeferredLayerUpdater::ImageSlot::clear(GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400233 if (mTextureRelease) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400234 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
235 this->releaseQueueOwnership(context);
236 }
Stan Ilievaaa9e832019-09-17 14:07:23 -0400237 // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
238 mTextureRelease->unref(true);
239 mTextureRelease = nullptr;
240 }
241
242 mBuffer = nullptr;
243}
244
Greg Daniel27e1fa22021-05-26 09:24:15 -0400245void DeferredLayerUpdater::ImageSlot::releaseQueueOwnership(GrDirectContext* context) {
246 LOG_ALWAYS_FATAL_IF(Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan);
247 if (mTextureRelease) {
248 mTextureRelease->releaseQueueOwnership(context);
249 }
250}
251
John Reck04fc5832014-02-05 16:38:25 -0800252} /* namespace uirenderer */
253} /* namespace android */