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