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