blob: 5a50245a376522f48ac1aada2fcc610bb6a2d611 [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"
24#include "Matrix.h"
25#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
79 mImageSlots.clear();
John Reck04fc5832014-02-05 16:38:25 -080080}
81
Derek Sollenberger674554f2014-02-19 16:47:32 +000082void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
Chris Craikbf6f0f22015-10-01 12:36:07 -070083 mAlpha = PaintUtils::getAlphaDirect(paint);
Mike Reed260ab722016-10-07 15:59:20 -040084 mMode = PaintUtils::getBlendModeDirect(paint);
Derek Sollenbergerbe3876c2018-04-20 16:13:31 -040085 if (paint) {
86 mColorFilter = paint->refColorFilter();
87 } else {
88 mColorFilter.reset();
89 }
John Reck04fc5832014-02-05 16:38:25 -080090}
91
Stan Ilievaaa9e832019-09-17 14:07:23 -040092static status_t createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, EGLDisplay* display,
93 int* releaseFence, void* handle) {
94 *display = EGL_NO_DISPLAY;
95 RenderState* renderState = (RenderState*)handle;
96 status_t err;
97 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
98 EglManager& eglManager = renderState->getRenderThread().eglManager();
99 *display = eglManager.eglDisplay();
100 err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
101 } else {
102 err = renderState->getRenderThread().vulkanManager().createReleaseFence(
103 releaseFence, renderState->getRenderThread().getGrContext());
104 }
105 return err;
106}
107
108static status_t fenceWait(int fence, void* handle) {
109 // Wait on the producer fence for the buffer to be ready.
110 status_t err;
111 RenderState* renderState = (RenderState*)handle;
112 if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
113 err = renderState->getRenderThread().eglManager().fenceWait(fence);
114 } else {
115 err = renderState->getRenderThread().vulkanManager().fenceWait(
116 fence, renderState->getRenderThread().getGrContext());
117 }
118 return err;
119}
120
Chris Craikd2dfd8f2015-12-16 14:27:20 -0800121void DeferredLayerUpdater::apply() {
sergeyv3e9999b2017-01-19 15:37:02 -0800122 if (!mLayer) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000123 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode);
sergeyv3e9999b2017-01-19 15:37:02 -0800124 }
125
John Reck04fc5832014-02-05 16:38:25 -0800126 mLayer->setColorFilter(mColorFilter);
127 mLayer->setAlpha(mAlpha, mMode);
128
John Reck25fbb3f2014-06-12 13:46:45 -0700129 if (mSurfaceTexture.get()) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000130 if (!mGLContextAttached) {
131 mGLContextAttached = true;
132 mUpdateTexImage = true;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400133 ASurfaceTexture_takeConsumerOwnership(mSurfaceTexture.get());
Stan Iliev85f90962018-08-31 18:35:06 +0000134 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000135 if (mUpdateTexImage) {
136 mUpdateTexImage = false;
Stan Ilievaaa9e832019-09-17 14:07:23 -0400137 float transformMatrix[16];
138 android_dataspace dataspace;
139 int slot;
140 bool newContent = false;
141 // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
142 // is necessary if the SurfaceTexture queue is in synchronous mode, and we
143 // cannot tell which mode it is in.
144 AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
145 mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &newContent,
146 createReleaseFence, fenceWait, &mRenderState);
147
148 if (hardwareBuffer) {
149 sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
150 hardwareBuffer, dataspace, newContent,
151 mRenderState.getRenderThread().getGrContext());
152 if (layerImage.get()) {
153 SkMatrix textureTransform;
154 mat4(transformMatrix).copyTo(textureTransform);
155 // force filtration if buffer size != layer size
156 bool forceFilter =
157 mWidth != layerImage->width() || mHeight != layerImage->height();
158 updateLayer(forceFilter, textureTransform, layerImage);
159 }
Stan Iliev564ca3e2018-09-04 22:00:00 +0000160 }
161 }
162
John Reck04fc5832014-02-05 16:38:25 -0800163 if (mTransform) {
Stan Iliev564ca3e2018-09-04 22:00:00 +0000164 mLayer->getTransform() = *mTransform;
Chris Craikd41c4d82015-01-05 15:51:13 -0800165 setTransform(nullptr);
John Reck04fc5832014-02-05 16:38:25 -0800166 }
167 }
John Reck04fc5832014-02-05 16:38:25 -0800168}
169
Stan Iliev564ca3e2018-09-04 22:00:00 +0000170void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform,
Stan Ilievaaa9e832019-09-17 14:07:23 -0400171 const sk_sp<SkImage>& layerImage) {
Greg Daniel45ec62b2017-01-04 14:27:00 -0500172 mLayer->setBlend(mBlend);
173 mLayer->setForceFilter(forceFilter);
174 mLayer->setSize(mWidth, mHeight);
Stan Iliev564ca3e2018-09-04 22:00:00 +0000175 mLayer->getTexTransform() = textureTransform;
Stan Iliev564ca3e2018-09-04 22:00:00 +0000176 mLayer->setImage(layerImage);
Greg Daniel45ec62b2017-01-04 14:27:00 -0500177}
178
John Reck918ad522014-06-27 14:45:25 -0700179void DeferredLayerUpdater::detachSurfaceTexture() {
180 if (mSurfaceTexture.get()) {
sergeyv00eb43d2017-02-13 14:34:15 -0800181 destroyLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800182 mSurfaceTexture = nullptr;
John Reck918ad522014-06-27 14:45:25 -0700183 }
184}
185
Stan Ilievaaa9e832019-09-17 14:07:23 -0400186sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
187 android_dataspace dataspace,
188 bool forceCreate,
189 GrContext* context) {
190 if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
191 forceCreate || mBuffer != buffer) {
192 if (buffer != mBuffer) {
193 clear();
194 }
195
196 if (!buffer) {
197 return nullptr;
198 }
199
200 if (!mTextureRelease) {
201 mTextureRelease = new AutoBackendTextureRelease(context, buffer);
202 } else {
203 mTextureRelease->newBufferContent(context);
204 }
205
206 mDataspace = dataspace;
207 mBuffer = buffer;
208 mTextureRelease->makeImage(buffer, dataspace, context);
209 }
210 return mTextureRelease ? mTextureRelease->getImage() : nullptr;
211}
212
213void DeferredLayerUpdater::ImageSlot::clear() {
214 if (mTextureRelease) {
215 // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
216 mTextureRelease->unref(true);
217 mTextureRelease = nullptr;
218 }
219
220 mBuffer = nullptr;
221}
222
John Reck04fc5832014-02-05 16:38:25 -0800223} /* namespace uirenderer */
224} /* namespace android */