DeferredLayerUpdater.cpp revision 00eb43dbc04083eab85fbb1a9589e2548f2004ed
1/* 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 18#include "GlLayer.h" 19#include "VkLayer.h" 20#include "renderstate/RenderState.h" 21#include "renderthread/EglManager.h" 22#include "renderthread/RenderTask.h" 23#include "utils/PaintUtils.h" 24 25namespace android { 26namespace uirenderer { 27 28DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn, 29 Layer::Api layerApi) 30 : mRenderState(renderState) 31 , mBlend(false) 32 , mSurfaceTexture(nullptr) 33 , mTransform(nullptr) 34 , mGLContextAttached(false) 35 , mUpdateTexImage(false) 36 , mLayer(nullptr) 37 , mLayerApi(layerApi) 38 , mCreateLayerFn(createLayerFn) { 39 renderState.registerDeferredLayerUpdater(this); 40} 41 42DeferredLayerUpdater::~DeferredLayerUpdater() { 43 SkSafeUnref(mColorFilter); 44 setTransform(nullptr); 45 mRenderState.unregisterDeferredLayerUpdater(this); 46 destroyLayer(); 47} 48 49void DeferredLayerUpdater::destroyLayer() { 50 if (!mLayer) { 51 return; 52 } 53 54 if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) { 55 status_t err = mSurfaceTexture->detachFromContext(); 56 mGLContextAttached = false; 57 if (err != 0) { 58 // TODO: Elevate to fatal exception 59 ALOGE("Failed to detach SurfaceTexture from context %d", err); 60 } 61 } 62 63 mLayer->postDecStrong(); 64 mLayer = nullptr; 65} 66 67void DeferredLayerUpdater::setPaint(const SkPaint* paint) { 68 mAlpha = PaintUtils::getAlphaDirect(paint); 69 mMode = PaintUtils::getBlendModeDirect(paint); 70 SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr; 71 SkRefCnt_SafeAssign(mColorFilter, colorFilter); 72} 73 74void DeferredLayerUpdater::apply() { 75 if (!mLayer) { 76 mLayer = mCreateLayerFn(mRenderState, mWidth, mHeight, mColorFilter, mAlpha, mMode, mBlend); 77 } 78 79 mLayer->setColorFilter(mColorFilter); 80 mLayer->setAlpha(mAlpha, mMode); 81 82 if (mSurfaceTexture.get()) { 83 if (mLayer->getApi() == Layer::Api::Vulkan) { 84 if (mUpdateTexImage) { 85 mUpdateTexImage = false; 86 doUpdateVkTexImage(); 87 } 88 } else { 89 LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, 90 "apply surfaceTexture with non GL backend %x, GL %x, VK %x", 91 mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 92 if (!mGLContextAttached) { 93 mGLContextAttached = true; 94 mUpdateTexImage = true; 95 mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId()); 96 } 97 if (mUpdateTexImage) { 98 mUpdateTexImage = false; 99 doUpdateTexImage(); 100 } 101 } 102 if (mTransform) { 103 mLayer->getTransform().load(*mTransform); 104 setTransform(nullptr); 105 } 106 } 107} 108 109void DeferredLayerUpdater::doUpdateTexImage() { 110 LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, 111 "doUpdateTexImage non GL backend %x, GL %x, VK %x", 112 mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 113 if (mSurfaceTexture->updateTexImage() == NO_ERROR) { 114 float transform[16]; 115 116 int64_t frameNumber = mSurfaceTexture->getFrameNumber(); 117 // If the GLConsumer queue is in synchronous mode, need to discard all 118 // but latest frame, using the frame number to tell when we no longer 119 // have newer frames to target. Since we can't tell which mode it is in, 120 // do this unconditionally. 121 int dropCounter = 0; 122 while (mSurfaceTexture->updateTexImage() == NO_ERROR) { 123 int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); 124 if (newFrameNumber == frameNumber) break; 125 frameNumber = newFrameNumber; 126 dropCounter++; 127 } 128 129 bool forceFilter = false; 130 sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); 131 if (buffer != nullptr) { 132 // force filtration if buffer size != layer size 133 forceFilter = mWidth != static_cast<int>(buffer->getWidth()) 134 || mHeight != static_cast<int>(buffer->getHeight()); 135 } 136 137 #if DEBUG_RENDERER 138 if (dropCounter > 0) { 139 RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); 140 } 141 #endif 142 mSurfaceTexture->getTransformMatrix(transform); 143 GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); 144 145 LOG_ALWAYS_FATAL_IF(renderTarget != GL_TEXTURE_2D && renderTarget != GL_TEXTURE_EXTERNAL_OES, 146 "doUpdateTexImage target %x, 2d %x, EXT %x", 147 renderTarget, GL_TEXTURE_2D, GL_TEXTURE_EXTERNAL_OES); 148 updateLayer(forceFilter, renderTarget, transform); 149 } 150} 151 152void DeferredLayerUpdater::doUpdateVkTexImage() { 153 LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::Vulkan, 154 "updateLayer non Vulkan backend %x, GL %x, VK %x", 155 mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); 156 157 static const mat4 identityMatrix; 158 updateLayer(false, GL_NONE, identityMatrix.data); 159 160 VkLayer* vkLayer = static_cast<VkLayer*>(mLayer); 161 vkLayer->updateTexture(); 162} 163 164void DeferredLayerUpdater::updateLayer(bool forceFilter, GLenum renderTarget, 165 const float* textureTransform) { 166 mLayer->setBlend(mBlend); 167 mLayer->setForceFilter(forceFilter); 168 mLayer->setSize(mWidth, mHeight); 169 mLayer->getTexTransform().load(textureTransform); 170 171 if (mLayer->getApi() == Layer::Api::OpenGL) { 172 GlLayer* glLayer = static_cast<GlLayer*>(mLayer); 173 if (renderTarget != glLayer->getRenderTarget()) { 174 glLayer->setRenderTarget(renderTarget); 175 glLayer->bindTexture(); 176 glLayer->setFilter(GL_NEAREST, false, true); 177 glLayer->setWrap(GL_CLAMP_TO_EDGE, false, true); 178 } 179 } 180} 181 182void DeferredLayerUpdater::detachSurfaceTexture() { 183 if (mSurfaceTexture.get()) { 184 destroyLayer(); 185 mSurfaceTexture = nullptr; 186 } 187} 188 189} /* namespace uirenderer */ 190} /* namespace android */ 191