blob: c0160705fd47a11593b88977ef8e6af5bb5dd0f3 [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.
Alec Mourief3ecd52024-09-24 21:00:32 +000022#include <statslog_hwui.h>
Stan Iliev5af5d302020-01-13 11:29:18 -050023#include <surfacetexture/surface_texture_platform.h>
Alec Mourid0001fe2021-11-22 10:09:22 -080024
Stan Ilievaaa9e832019-09-17 14:07:23 -040025#include "AutoBackendTextureRelease.h"
bsears9df09ccf2021-08-06 15:18:26 +000026#include "Matrix.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040027#include "Properties.h"
Alec Mourid0001fe2021-11-22 10:09:22 -080028#include "android/hdr_metadata.h"
sergeyv3e9999b2017-01-19 15:37:02 -080029#include "renderstate/RenderState.h"
Stan Ilievaaa9e832019-09-17 14:07:23 -040030#include "renderthread/EglManager.h"
31#include "renderthread/RenderThread.h"
32#include "renderthread/VulkanManager.h"
33
34using namespace android::uirenderer::renderthread;
John Reck04fc5832014-02-05 16:38:25 -080035
36namespace android {
37namespace uirenderer {
38
Stan Iliev564ca3e2018-09-04 22:00:00 +000039DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState)
sergeyv3e9999b2017-01-19 15:37:02 -080040 : mRenderState(renderState)
41 , mBlend(false)
Stan Iliev5af5d302020-01-13 11:29:18 -050042 , mSurfaceTexture(nullptr, [](ASurfaceTexture*) {})
Chris Craikd41c4d82015-01-05 15:51:13 -080043 , mTransform(nullptr)
sergeyv00eb43d2017-02-13 14:34:15 -080044 , mGLContextAttached(false)
John Reck04fc5832014-02-05 16:38:25 -080045 , mUpdateTexImage(false)
Stan Iliev564ca3e2018-09-04 22:00:00 +000046 , mLayer(nullptr) {
Derek Sollenberger28a4d992018-09-20 13:37:24 -040047 renderState.registerContextCallback(this);
John Reck04fc5832014-02-05 16:38:25 -080048}
49
50DeferredLayerUpdater::~DeferredLayerUpdater() {
Chris Craikd41c4d82015-01-05 15:51:13 -080051 setTransform(nullptr);
Derek Sollenberger28a4d992018-09-20 13:37:24 -040052 mRenderState.removeContextCallback(this);
53 destroyLayer();
Alec Mourief3ecd52024-09-24 21:00:32 +000054 if (mFirstTimeForDataspace > std::chrono::steady_clock::time_point::min()) {
55 auto currentTime = std::chrono::steady_clock::now();
56 stats_write(stats::TEXTURE_VIEW_EVENT, static_cast<int32_t>(getuid()),
57 static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
58 currentTime - mFirstTimeForDataspace)
59 .count()),
60 mDataspace);
61 }
Derek Sollenberger28a4d992018-09-20 13:37:24 -040062}
63
Stan Ilievaaa9e832019-09-17 14:07:23 -040064void DeferredLayerUpdater::setSurfaceTexture(AutoTextureRelease&& consumer) {
65 mSurfaceTexture = std::move(consumer);
Fedor Kudasovd501e102019-06-21 10:22:53 +010066
Stan Ilievaaa9e832019-09-17 14:07:23 -040067 GLenum target = ASurfaceTexture_getCurrentTextureTarget(mSurfaceTexture.get());
68 LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
69 "set unsupported SurfaceTexture with target %x", target);
Fedor Kudasovd501e102019-06-21 10:22:53 +010070}
71
Derek Sollenberger28a4d992018-09-20 13:37:24 -040072void DeferredLayerUpdater::onContextDestroyed() {
sergeyv3e9999b2017-01-19 15:37:02 -080073 destroyLayer();
74}
75
76void DeferredLayerUpdater::destroyLayer() {
sergeyv00eb43d2017-02-13 14:34:15 -080077 if (!mLayer) {
78 return;
sergeyv3e9999b2017-01-19 15:37:02 -080079 }
sergeyv00eb43d2017-02-13 14:34:15 -080080
Stan Iliev564ca3e2018-09-04 22:00:00 +000081 if (mSurfaceTexture.get() && mGLContextAttached) {
Stan Ilievaaa9e832019-09-17 14:07:23 -040082 ASurfaceTexture_releaseConsumerOwnership(mSurfaceTexture.get());
sergeyv00eb43d2017-02-13 14:34:15 -080083 mGLContextAttached = false;
sergeyv00eb43d2017-02-13 14:34:15 -080084 }
85
86 mLayer->postDecStrong();
Stan Iliev1a025a72018-09-05 16:35:11 -040087
sergeyv00eb43d2017-02-13 14:34:15 -080088 mLayer = nullptr;
Stan Ilievaaa9e832019-09-17 14:07:23 -040089
Greg Daniel27e1fa22021-05-26 09:24:15 -040090 for (auto& [index, slot] : mImageSlots) {
91 slot.clear(mRenderState.getRenderThread().getGrContext());
92 }
Stan Ilievaaa9e832019-09-17 14:07:23 -040093 mImageSlots.clear();
John Reck04fc5832014-02-05 16:38:25 -080094}
95
Derek Sollenberger674554f2014-02-19 16:47:32 +000096void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
Chris Craikbf6f0f22015-10-01 12:36:07 -070097 mAlpha = PaintUtils::getAlphaDirect(paint);
Mike Reed260ab722016-10-07 15:59:20 -040098 mMode = PaintUtils::getBlendModeDirect(paint);
Derek Sollenbergerbe3876c2018-04-20 16:13:31 -040099 if (paint) {
100 mColorFilter = paint->refColorFilter();
101 } else {
102 mColorFilter.reset();
103 }
John Reck04fc5832014-02-05 16:38:25 -0800104}
105
Greg Daniel27e1fa22021-05-26 09:24:15 -0400106status_t DeferredLayerUpdater::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
107 EGLDisplay* display, int* releaseFence,
108 void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400109 *display = EGL_NO_DISPLAY;
Greg Daniel27e1fa22021-05-26 09:24:15 -0400110 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
111 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400112 status_t err;
113 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400114 EglManager& eglManager = renderState.getRenderThread().eglManager();
Stan Ilievaaa9e832019-09-17 14:07:23 -0400115 *display = eglManager.eglDisplay();
116 err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
117 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400118 int previousSlot = dlu->mCurrentSlot;
119 if (previousSlot != -1) {
120 dlu->mImageSlots[previousSlot].releaseQueueOwnership(
121 renderState.getRenderThread().getGrContext());
122 }
123 err = renderState.getRenderThread().vulkanManager().createReleaseFence(
124 releaseFence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400125 }
126 return err;
127}
128
Greg Daniel27e1fa22021-05-26 09:24:15 -0400129status_t DeferredLayerUpdater::fenceWait(int fence, void* handle) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400130 // Wait on the producer fence for the buffer to be ready.
131 status_t err;
Greg Daniel27e1fa22021-05-26 09:24:15 -0400132 DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
133 RenderState& renderState = dlu->mRenderState;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400134 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400135 err = renderState.getRenderThread().eglManager().fenceWait(fence);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400136 } else {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400137 err = renderState.getRenderThread().vulkanManager().fenceWait(
138 fence, renderState.getRenderThread().getGrContext());
Stan Ilievaaa9e832019-09-17 14:07:23 -0400139 }
140 return err;
141}
142
Chris Craikd2dfd8f2015-12-16 14:27:20 -0800143void DeferredLayerUpdater::apply() {
sergeyv3e9999b2017-01-19 15:37:02 -0800144 if (!mLayer) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000145 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode);
sergeyv3e9999b2017-01-19 15:37:02 -0800146 }
147
John Reck04fc5832014-02-05 16:38:25 -0800148 mLayer->setColorFilter(mColorFilter);
149 mLayer->setAlpha(mAlpha, mMode);
150
John Reck25fbb3f2014-06-12 13:46:45 -0700151 if (mSurfaceTexture.get()) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000152 if (!mGLContextAttached) {
153 mGLContextAttached = true;
154 mUpdateTexImage = true;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400155 ASurfaceTexture_takeConsumerOwnership(mSurfaceTexture.get());
Stan Iliev85f90962018-08-31 18:35:06 +0000156 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000157 if (mUpdateTexImage) {
158 mUpdateTexImage = false;
bsears9df09ccf2021-08-06 15:18:26 +0000159 float transformMatrix[16];
Stan Ilievaaa9e832019-09-17 14:07:23 -0400160 android_dataspace dataspace;
Alec Mourid0001fe2021-11-22 10:09:22 -0800161 AHdrMetadataType hdrMetadataType;
162 android_cta861_3_metadata cta861_3;
163 android_smpte2086_metadata smpte2086;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400164 int slot;
165 bool newContent = false;
ramindanibd4971b2021-08-06 22:38:45 +0000166 ARect currentCrop;
167 uint32_t outTransform;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400168 // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
169 // is necessary if the SurfaceTexture queue is in synchronous mode, and we
170 // cannot tell which mode it is in.
171 AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
Alec Mourid0001fe2021-11-22 10:09:22 -0800172 mSurfaceTexture.get(), &slot, &dataspace, &hdrMetadataType, &cta861_3,
173 &smpte2086, transformMatrix, &outTransform, &newContent, createReleaseFence,
174 fenceWait, this, &currentCrop);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400175
176 if (hardwareBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400177 mCurrentSlot = slot;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400178 sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
179 hardwareBuffer, dataspace, newContent,
180 mRenderState.getRenderThread().getGrContext());
John Reck8df7f3c2022-09-29 13:19:54 -0400181 AHardwareBuffer_Desc bufferDesc;
182 AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);
Stan Ilievd125b442020-07-16 17:03:27 -0400183 // unref to match the ref added by ASurfaceTexture_dequeueBuffer. eglCreateImageKHR
184 // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer.
185 AHardwareBuffer_release(hardwareBuffer);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400186 if (layerImage.get()) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400187 // force filtration if buffer size != layer size
188 bool forceFilter =
189 mWidth != layerImage->width() || mHeight != layerImage->height();
ramindani3952ed62021-08-12 15:55:12 +0000190 SkRect currentCropRect =
191 SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right,
192 currentCrop.bottom);
Alec Mourid0001fe2021-11-22 10:09:22 -0800193
194 float maxLuminanceNits = -1.f;
195 if (hdrMetadataType & HDR10_SMPTE2086) {
196 maxLuminanceNits = std::max(smpte2086.maxLuminance, maxLuminanceNits);
197 }
198
199 if (hdrMetadataType & HDR10_CTA861_3) {
200 maxLuminanceNits =
201 std::max(cta861_3.maxContentLightLevel, maxLuminanceNits);
202 }
John Reck8df7f3c2022-09-29 13:19:54 -0400203 mLayer->setBufferFormat(bufferDesc.format);
Alec Mourid0001fe2021-11-22 10:09:22 -0800204 updateLayer(forceFilter, layerImage, outTransform, currentCropRect,
205 maxLuminanceNits);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400206 }
Alec Mourief3ecd52024-09-24 21:00:32 +0000207
208 if (dataspace != mDataspace ||
209 mFirstTimeForDataspace == std::chrono::steady_clock::time_point::min()) {
210 auto currentTime = std::chrono::steady_clock::now();
211 if (mFirstTimeForDataspace > std::chrono::steady_clock::time_point::min()) {
212 stats_write(stats::TEXTURE_VIEW_EVENT, static_cast<int32_t>(getuid()),
213 static_cast<int64_t>(
214 std::chrono::duration_cast<std::chrono::milliseconds>(
215 currentTime - mFirstTimeForDataspace)
216 .count()),
217 mDataspace);
218 }
219 mFirstTimeForDataspace = currentTime;
220 mDataspace = dataspace;
221 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000222 }
223 }
224
John Reck04fc5832014-02-05 16:38:25 -0800225 if (mTransform) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000226 mLayer->getTransform() = *mTransform;
Chris Craikd41c4d82015-01-05 15:51:13 -0800227 setTransform(nullptr);
John Reck04fc5832014-02-05 16:38:25 -0800228 }
229 }
John Reck04fc5832014-02-05 16:38:25 -0800230}
231
ramindani3952ed62021-08-12 15:55:12 +0000232void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage,
Alec Mourid0001fe2021-11-22 10:09:22 -0800233 const uint32_t transform, SkRect currentCrop,
234 float maxLuminanceNits) {
Greg Daniel45ec62b2017-01-04 14:27:00 -0500235 mLayer->setBlend(mBlend);
236 mLayer->setForceFilter(forceFilter);
237 mLayer->setSize(mWidth, mHeight);
ramindani3952ed62021-08-12 15:55:12 +0000238 mLayer->setCurrentCropRect(currentCrop);
239 mLayer->setWindowTransform(transform);
Stan Iliev564ca3e2018-09-04 22:00:00 +0000240 mLayer->setImage(layerImage);
Alec Mourid0001fe2021-11-22 10:09:22 -0800241 mLayer->setMaxLuminanceNits(maxLuminanceNits);
Greg Daniel45ec62b2017-01-04 14:27:00 -0500242}
243
John Reck918ad522014-06-27 14:45:25 -0700244void DeferredLayerUpdater::detachSurfaceTexture() {
245 if (mSurfaceTexture.get()) {
sergeyv00eb43d2017-02-13 14:34:15 -0800246 destroyLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800247 mSurfaceTexture = nullptr;
John Reck918ad522014-06-27 14:45:25 -0700248 }
249}
250
Stan Ilievaaa9e832019-09-17 14:07:23 -0400251sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
252 android_dataspace dataspace,
253 bool forceCreate,
Adlai Hollerf8c434e2020-07-27 11:42:45 -0400254 GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400255 if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
256 forceCreate || mBuffer != buffer) {
257 if (buffer != mBuffer) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400258 clear(context);
Stan Ilievaaa9e832019-09-17 14:07:23 -0400259 }
260
261 if (!buffer) {
262 return nullptr;
263 }
264
265 if (!mTextureRelease) {
266 mTextureRelease = new AutoBackendTextureRelease(context, buffer);
267 } else {
268 mTextureRelease->newBufferContent(context);
269 }
270
271 mDataspace = dataspace;
272 mBuffer = buffer;
273 mTextureRelease->makeImage(buffer, dataspace, context);
274 }
275 return mTextureRelease ? mTextureRelease->getImage() : nullptr;
276}
277
Greg Daniel27e1fa22021-05-26 09:24:15 -0400278void DeferredLayerUpdater::ImageSlot::clear(GrDirectContext* context) {
Stan Ilievaaa9e832019-09-17 14:07:23 -0400279 if (mTextureRelease) {
Greg Daniel27e1fa22021-05-26 09:24:15 -0400280 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
281 this->releaseQueueOwnership(context);
282 }
Stan Ilievaaa9e832019-09-17 14:07:23 -0400283 // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
284 mTextureRelease->unref(true);
285 mTextureRelease = nullptr;
286 }
287
288 mBuffer = nullptr;
289}
290
Greg Daniel27e1fa22021-05-26 09:24:15 -0400291void DeferredLayerUpdater::ImageSlot::releaseQueueOwnership(GrDirectContext* context) {
292 LOG_ALWAYS_FATAL_IF(Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan);
293 if (mTextureRelease) {
294 mTextureRelease->releaseQueueOwnership(context);
295 }
296}
297
John Reck04fc5832014-02-05 16:38:25 -0800298} /* namespace uirenderer */
299} /* namespace android */