104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck/*
204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * Copyright (C) 2014 The Android Open Source Project
304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck *
404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * Licensed under the Apache License, Version 2.0 (the "License");
504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * you may not use this file except in compliance with the License.
604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * You may obtain a copy of the License at
704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck *
804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck *      http://www.apache.org/licenses/LICENSE-2.0
904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck *
1004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * Unless required by applicable law or agreed to in writing, software
1104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * distributed under the License is distributed on an "AS IS" BASIS,
1204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * See the License for the specific language governing permissions and
1404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck * limitations under the License.
1504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck */
1604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck#include "DeferredLayerUpdater.h"
1704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
188cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel#include "GlLayer.h"
1945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel#include "VkLayer.h"
203e9999bd866fac71c72e6b484a9836c87c328a08sergeyv#include "renderstate/RenderState.h"
21749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck#include "renderthread/EglManager.h"
22749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck#include "renderthread/RenderTask.h"
235e00c7ce063116c11315639f0035aca8ad73e8ccChris Craik#include "utils/PaintUtils.h"
2404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
2504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace android {
2604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace uirenderer {
2704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
283e9999bd866fac71c72e6b484a9836c87c328a08sergeyvDeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn,
291bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                                           Layer::Api layerApi)
303e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        : mRenderState(renderState)
313e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        , mBlend(false)
323e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        , mSurfaceTexture(nullptr)
33d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mTransform(nullptr)
3400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        , mGLContextAttached(false)
3504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mUpdateTexImage(false)
363e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        , mLayer(nullptr)
373e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        , mLayerApi(layerApi)
383e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        , mCreateLayerFn(createLayerFn) {
393e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    renderState.registerDeferredLayerUpdater(this);
4004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
4104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
4204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::~DeferredLayerUpdater() {
43d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    setTransform(nullptr);
443e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    mRenderState.unregisterDeferredLayerUpdater(this);
453e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    destroyLayer();
463e9999bd866fac71c72e6b484a9836c87c328a08sergeyv}
473e9999bd866fac71c72e6b484a9836c87c328a08sergeyv
483e9999bd866fac71c72e6b484a9836c87c328a08sergeyvvoid DeferredLayerUpdater::destroyLayer() {
4900eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv    if (!mLayer) {
5000eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        return;
5100eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv    }
5200eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv
5300eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv    if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) {
5400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        status_t err = mSurfaceTexture->detachFromContext();
5500eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        mGLContextAttached = false;
5600eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        if (err != 0) {
5700eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv            // TODO: Elevate to fatal exception
5800eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv            ALOGE("Failed to detach SurfaceTexture from context %d", err);
5900eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        }
603e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    }
6100eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv
6200eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv    mLayer->postDecStrong();
6300eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv    mLayer = nullptr;
6404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
6504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
66674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenbergervoid DeferredLayerUpdater::setPaint(const SkPaint* paint) {
67bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik    mAlpha = PaintUtils::getAlphaDirect(paint);
68260ab726486317496bc12a57d599ea96dcde3284Mike Reed    mMode = PaintUtils::getBlendModeDirect(paint);
69551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger    if (paint) {
70551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger        mColorFilter = paint->refColorFilter();
71551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger    } else {
72551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger        mColorFilter.reset();
73551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger    }
7404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
7504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
76d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craikvoid DeferredLayerUpdater::apply() {
773e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    if (!mLayer) {
783e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        mLayer = mCreateLayerFn(mRenderState, mWidth, mHeight, mColorFilter, mAlpha, mMode, mBlend);
793e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    }
803e9999bd866fac71c72e6b484a9836c87c328a08sergeyv
8104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setColorFilter(mColorFilter);
8204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setAlpha(mAlpha, mMode);
8304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
8425fbb3fa1138675379102a44405852555cefccbdJohn Reck    if (mSurfaceTexture.get()) {
8545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel        if (mLayer->getApi() == Layer::Api::Vulkan) {
8645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            if (mUpdateTexImage) {
8745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                mUpdateTexImage = false;
8845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                doUpdateVkTexImage();
8945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            }
9045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel        } else {
9145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
9245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                                "apply surfaceTexture with non GL backend %x, GL %x, VK %x",
9345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                                mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
9400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv            if (!mGLContextAttached) {
9500eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv                mGLContextAttached = true;
9600eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv                mUpdateTexImage = true;
9745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());
9845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            }
9945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            if (mUpdateTexImage) {
10045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                mUpdateTexImage = false;
10145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel                doUpdateTexImage();
10245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel            }
10309df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik            GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
10409df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik            static_cast<GlLayer*>(mLayer)->setRenderTarget(renderTarget);
10504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
10604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mTransform) {
10704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mLayer->getTransform().load(*mTransform);
108d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik            setTransform(nullptr);
10904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
11004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
11104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
11204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
11304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::doUpdateTexImage() {
1148cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel    LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
1151bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                        "doUpdateTexImage non GL backend %x, GL %x, VK %x", mLayer->getApi(),
1161bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                        Layer::Api::OpenGL, Layer::Api::Vulkan);
11704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
11804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        float transform[16];
11904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
12004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int64_t frameNumber = mSurfaceTexture->getFrameNumber();
12104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // If the GLConsumer queue is in synchronous mode, need to discard all
12204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // but latest frame, using the frame number to tell when we no longer
12304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // have newer frames to target. Since we can't tell which mode it is in,
12404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // do this unconditionally.
12504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int dropCounter = 0;
12604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        while (mSurfaceTexture->updateTexImage() == NO_ERROR) {
12704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber();
12804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            if (newFrameNumber == frameNumber) break;
12904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            frameNumber = newFrameNumber;
13004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            dropCounter++;
13104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
1329757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
1339757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        bool forceFilter = false;
1349757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
135d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        if (buffer != nullptr) {
1369757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik            // force filtration if buffer size != layer size
1371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            forceFilter = mWidth != static_cast<int>(buffer->getWidth()) ||
1381bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                          mHeight != static_cast<int>(buffer->getHeight());
1399757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        }
1409757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
1411bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#if DEBUG_RENDERER
14204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (dropCounter > 0) {
14304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
14404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
1451bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#endif
14604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mSurfaceTexture->getTransformMatrix(transform);
14704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
148551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger        updateLayer(forceFilter, transform, mSurfaceTexture->getCurrentDataSpace());
14956ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger    }
15056ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger}
15156ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger
15245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid DeferredLayerUpdater::doUpdateVkTexImage() {
15345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::Vulkan,
1541bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                        "updateLayer non Vulkan backend %x, GL %x, VK %x", mLayer->getApi(),
1551bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                        Layer::Api::OpenGL, Layer::Api::Vulkan);
15645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel
15745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    static const mat4 identityMatrix;
158551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger    updateLayer(false, identityMatrix.data, HAL_DATASPACE_UNKNOWN);
15945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel
16045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    VkLayer* vkLayer = static_cast<VkLayer*>(mLayer);
16145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    vkLayer->updateTexture();
16245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel}
16345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel
164551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenbergervoid DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform,
165551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger                                       android_dataspace dataspace) {
16645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    mLayer->setBlend(mBlend);
16745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    mLayer->setForceFilter(forceFilter);
16845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    mLayer->setSize(mWidth, mHeight);
16945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    mLayer->getTexTransform().load(textureTransform);
170551d08e2d50c7f73c5eb65fd366b92efba4f0ed5Derek Sollenberger    mLayer->setDataSpace(dataspace);
17145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel}
17245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel
173918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reckvoid DeferredLayerUpdater::detachSurfaceTexture() {
174918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    if (mSurfaceTexture.get()) {
17500eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv        destroyLayer();
176d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        mSurfaceTexture = nullptr;
177918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    }
178918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck}
179918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck
18004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */
18104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */
182