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, 293e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 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() { 43674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger SkSafeUnref(mColorFilter); 44d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik setTransform(nullptr); 453e9999bd866fac71c72e6b484a9836c87c328a08sergeyv mRenderState.unregisterDeferredLayerUpdater(this); 463e9999bd866fac71c72e6b484a9836c87c328a08sergeyv destroyLayer(); 473e9999bd866fac71c72e6b484a9836c87c328a08sergeyv} 483e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 493e9999bd866fac71c72e6b484a9836c87c328a08sergeyvvoid DeferredLayerUpdater::destroyLayer() { 5000eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv if (!mLayer) { 5100eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv return; 5200eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv } 5300eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv 5400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) { 5500eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv status_t err = mSurfaceTexture->detachFromContext(); 5600eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv mGLContextAttached = false; 5700eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv if (err != 0) { 5800eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv // TODO: Elevate to fatal exception 5900eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv ALOGE("Failed to detach SurfaceTexture from context %d", err); 6000eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv } 613e9999bd866fac71c72e6b484a9836c87c328a08sergeyv } 6200eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv 6300eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv mLayer->postDecStrong(); 6400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv mLayer = nullptr; 6504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 6604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 67674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenbergervoid DeferredLayerUpdater::setPaint(const SkPaint* paint) { 68bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik mAlpha = PaintUtils::getAlphaDirect(paint); 69260ab726486317496bc12a57d599ea96dcde3284Mike Reed mMode = PaintUtils::getBlendModeDirect(paint); 70d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr; 7104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck SkRefCnt_SafeAssign(mColorFilter, colorFilter); 7204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 7304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 74d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craikvoid DeferredLayerUpdater::apply() { 753e9999bd866fac71c72e6b484a9836c87c328a08sergeyv if (!mLayer) { 763e9999bd866fac71c72e6b484a9836c87c328a08sergeyv mLayer = mCreateLayerFn(mRenderState, mWidth, mHeight, mColorFilter, mAlpha, mMode, mBlend); 773e9999bd866fac71c72e6b484a9836c87c328a08sergeyv } 783e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 7904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->setColorFilter(mColorFilter); 8004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->setAlpha(mAlpha, mMode); 8104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 8225fbb3fa1138675379102a44405852555cefccbdJohn Reck if (mSurfaceTexture.get()) { 8345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel if (mLayer->getApi() == Layer::Api::Vulkan) { 8445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel if (mUpdateTexImage) { 8545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mUpdateTexImage = false; 8645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel doUpdateVkTexImage(); 8745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel } 8845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel } else { 8945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, 9045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "apply surfaceTexture with non GL backend %x, GL %x, VK %x", 9145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 9200eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv if (!mGLContextAttached) { 9300eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv mGLContextAttached = true; 9400eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv mUpdateTexImage = true; 9545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId()); 9645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel } 9745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel if (mUpdateTexImage) { 9845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mUpdateTexImage = false; 9945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel doUpdateTexImage(); 10045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel } 10109df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); 10209df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik static_cast<GlLayer*>(mLayer)->setRenderTarget(renderTarget); 10304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 10404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mTransform) { 10504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->getTransform().load(*mTransform); 106d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik setTransform(nullptr); 10704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 10804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 10904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 11004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 11104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::doUpdateTexImage() { 1128cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, 1138cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel "doUpdateTexImage non GL backend %x, GL %x, VK %x", 1148cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 11504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mSurfaceTexture->updateTexImage() == NO_ERROR) { 11604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck float transform[16]; 11704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 11804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int64_t frameNumber = mSurfaceTexture->getFrameNumber(); 11904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // If the GLConsumer queue is in synchronous mode, need to discard all 12004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // but latest frame, using the frame number to tell when we no longer 12104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // have newer frames to target. Since we can't tell which mode it is in, 12204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // do this unconditionally. 12304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int dropCounter = 0; 12404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck while (mSurfaceTexture->updateTexImage() == NO_ERROR) { 12504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); 12604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (newFrameNumber == frameNumber) break; 12704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck frameNumber = newFrameNumber; 12804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck dropCounter++; 12904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 1309757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik 1319757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik bool forceFilter = false; 1329757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); 133d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik if (buffer != nullptr) { 1349757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik // force filtration if buffer size != layer size 13532d2e769ea6052aca2232c571a82ed7a7f8c996aDan Stoza forceFilter = mWidth != static_cast<int>(buffer->getWidth()) 13632d2e769ea6052aca2232c571a82ed7a7f8c996aDan Stoza || mHeight != static_cast<int>(buffer->getHeight()); 1379757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik } 1389757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik 13904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck #if DEBUG_RENDERER 14004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (dropCounter > 0) { 14104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); 14204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 14304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck #endif 14404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mSurfaceTexture->getTransformMatrix(transform); 14504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 14609df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik updateLayer(forceFilter, transform); 14756ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger } 14856ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger} 14956ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger 15045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid DeferredLayerUpdater::doUpdateVkTexImage() { 15145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::Vulkan, 15245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "updateLayer non Vulkan backend %x, GL %x, VK %x", 15345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 15445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 15545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel static const mat4 identityMatrix; 15609df887c9078a34f2bda32c83734b7f75c0a60ffChris Craik updateLayer(false, identityMatrix.data); 15745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 15845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel VkLayer* vkLayer = static_cast<VkLayer*>(mLayer); 15945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel vkLayer->updateTexture(); 16045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 16145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 16209df887c9078a34f2bda32c83734b7f75c0a60ffChris Craikvoid DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform) { 16345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->setBlend(mBlend); 16445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->setForceFilter(forceFilter); 16545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->setSize(mWidth, mHeight); 16645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayer->getTexTransform().load(textureTransform); 16745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 16845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 169918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reckvoid DeferredLayerUpdater::detachSurfaceTexture() { 170918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck if (mSurfaceTexture.get()) { 17100eb43dbc04083eab85fbb1a9589e2548f2004edsergeyv destroyLayer(); 172d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mSurfaceTexture = nullptr; 173918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck } 174918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck} 175918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck 17604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */ 17704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */ 178