DeferredLayerUpdater.cpp revision 260ab726486317496bc12a57d599ea96dcde3284
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 "renderthread/EglManager.h" 19#include "renderthread/RenderTask.h" 20#include "utils/PaintUtils.h" 21 22namespace android { 23namespace uirenderer { 24 25DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer) 26 : mSurfaceTexture(nullptr) 27 , mTransform(nullptr) 28 , mNeedsGLContextAttach(false) 29 , mUpdateTexImage(false) 30 , mLayer(layer) { 31 mWidth = mLayer->getWidth(); 32 mHeight = mLayer->getHeight(); 33 mBlend = mLayer->isBlend(); 34 mColorFilter = SkSafeRef(mLayer->getColorFilter()); 35 mAlpha = mLayer->getAlpha(); 36 mMode = mLayer->getMode(); 37} 38 39DeferredLayerUpdater::~DeferredLayerUpdater() { 40 SkSafeUnref(mColorFilter); 41 setTransform(nullptr); 42 mLayer->postDecStrong(); 43 mLayer = nullptr; 44} 45 46void DeferredLayerUpdater::setPaint(const SkPaint* paint) { 47 mAlpha = PaintUtils::getAlphaDirect(paint); 48 mMode = PaintUtils::getBlendModeDirect(paint); 49 SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr; 50 SkRefCnt_SafeAssign(mColorFilter, colorFilter); 51} 52 53void DeferredLayerUpdater::apply() { 54 mLayer->setColorFilter(mColorFilter); 55 mLayer->setAlpha(mAlpha, mMode); 56 57 if (mSurfaceTexture.get()) { 58 if (mNeedsGLContextAttach) { 59 mNeedsGLContextAttach = false; 60 mSurfaceTexture->attachToContext(mLayer->getTextureId()); 61 } 62 if (mUpdateTexImage) { 63 mUpdateTexImage = false; 64 doUpdateTexImage(); 65 } 66 if (mTransform) { 67 mLayer->getTransform().load(*mTransform); 68 setTransform(nullptr); 69 } 70 } 71} 72 73void DeferredLayerUpdater::doUpdateTexImage() { 74 if (mSurfaceTexture->updateTexImage() == NO_ERROR) { 75 float transform[16]; 76 77 int64_t frameNumber = mSurfaceTexture->getFrameNumber(); 78 // If the GLConsumer queue is in synchronous mode, need to discard all 79 // but latest frame, using the frame number to tell when we no longer 80 // have newer frames to target. Since we can't tell which mode it is in, 81 // do this unconditionally. 82 int dropCounter = 0; 83 while (mSurfaceTexture->updateTexImage() == NO_ERROR) { 84 int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); 85 if (newFrameNumber == frameNumber) break; 86 frameNumber = newFrameNumber; 87 dropCounter++; 88 } 89 90 bool forceFilter = false; 91 sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); 92 if (buffer != nullptr) { 93 // force filtration if buffer size != layer size 94 forceFilter = mWidth != static_cast<int>(buffer->getWidth()) 95 || mHeight != static_cast<int>(buffer->getHeight()); 96 } 97 98 #if DEBUG_RENDERER 99 if (dropCounter > 0) { 100 RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); 101 } 102 #endif 103 mSurfaceTexture->getTransformMatrix(transform); 104 GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); 105 106 LOG_ALWAYS_FATAL_IF(renderTarget != GL_TEXTURE_2D && renderTarget != GL_TEXTURE_EXTERNAL_OES, 107 "doUpdateTexImage target %x, 2d %x, EXT %x", 108 renderTarget, GL_TEXTURE_2D, GL_TEXTURE_EXTERNAL_OES); 109 updateLayer(forceFilter, renderTarget, transform); 110 } 111} 112 113void DeferredLayerUpdater::updateLayer(bool forceFilter, GLenum renderTarget, 114 const float* textureTransform) { 115 mLayer->setBlend(mBlend); 116 mLayer->setForceFilter(forceFilter); 117 mLayer->setSize(mWidth, mHeight); 118 mLayer->getTexTransform().load(textureTransform); 119 120 if (renderTarget != mLayer->getRenderTarget()) { 121 mLayer->setRenderTarget(renderTarget); 122 mLayer->bindTexture(); 123 mLayer->setFilter(GL_NEAREST, false, true); 124 mLayer->setWrap(GL_CLAMP_TO_EDGE, false, true); 125 } 126} 127 128void DeferredLayerUpdater::detachSurfaceTexture() { 129 if (mSurfaceTexture.get()) { 130 status_t err = mSurfaceTexture->detachFromContext(); 131 if (err != 0) { 132 // TODO: Elevate to fatal exception 133 ALOGE("Failed to detach SurfaceTexture from context %d", err); 134 } 135 mSurfaceTexture = nullptr; 136 mLayer->clearTexture(); 137 } 138} 139 140} /* namespace uirenderer */ 141} /* namespace android */ 142