DeferredLayerUpdater.cpp revision 68bfe0a37a0dcef52abd81688d8520c5d16e1a85
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 "OpenGLRenderer.h" 19 20#include "LayerRenderer.h" 21 22namespace android { 23namespace uirenderer { 24 25static void defaultLayerDestroyer(Layer* layer) { 26 Caches::getInstance().resourceCache.decrementRefcount(layer); 27} 28 29DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer) 30 : mSurfaceTexture(0) 31 , mTransform(0) 32 , mNeedsGLContextAttach(false) 33 , mUpdateTexImage(false) 34 , mLayer(layer) 35 , mCaches(Caches::getInstance()) 36 , mDestroyer(destroyer) { 37 mWidth = mLayer->layer.getWidth(); 38 mHeight = mLayer->layer.getHeight(); 39 mBlend = mLayer->isBlend(); 40 mColorFilter = SkSafeRef(mLayer->getColorFilter()); 41 mAlpha = mLayer->getAlpha(); 42 mMode = mLayer->getMode(); 43 44 if (!mDestroyer) { 45 mDestroyer = defaultLayerDestroyer; 46 } 47} 48 49DeferredLayerUpdater::~DeferredLayerUpdater() { 50 SkSafeUnref(mColorFilter); 51 setTransform(0); 52 mDestroyer(mLayer); 53} 54 55void DeferredLayerUpdater::setPaint(const SkPaint* paint) { 56 OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode); 57 SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL; 58 SkRefCnt_SafeAssign(mColorFilter, colorFilter); 59} 60 61bool DeferredLayerUpdater::apply() { 62 bool success = true; 63 // These properties are applied the same to both layer types 64 mLayer->setColorFilter(mColorFilter); 65 mLayer->setAlpha(mAlpha, mMode); 66 67 if (mSurfaceTexture.get()) { 68 if (mNeedsGLContextAttach) { 69 mNeedsGLContextAttach = false; 70 mSurfaceTexture->attachToContext(mLayer->getTexture()); 71 } 72 if (mUpdateTexImage) { 73 mUpdateTexImage = false; 74 doUpdateTexImage(); 75 } 76 if (mTransform) { 77 mLayer->getTransform().load(*mTransform); 78 setTransform(0); 79 } 80 } 81 return success; 82} 83 84void DeferredLayerUpdater::doUpdateTexImage() { 85 if (mSurfaceTexture->updateTexImage() == NO_ERROR) { 86 float transform[16]; 87 88 int64_t frameNumber = mSurfaceTexture->getFrameNumber(); 89 // If the GLConsumer queue is in synchronous mode, need to discard all 90 // but latest frame, using the frame number to tell when we no longer 91 // have newer frames to target. Since we can't tell which mode it is in, 92 // do this unconditionally. 93 int dropCounter = 0; 94 while (mSurfaceTexture->updateTexImage() == NO_ERROR) { 95 int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); 96 if (newFrameNumber == frameNumber) break; 97 frameNumber = newFrameNumber; 98 dropCounter++; 99 } 100 101 bool forceFilter = false; 102 sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); 103 if (buffer != NULL) { 104 // force filtration if buffer size != layer size 105 forceFilter = mWidth != buffer->getWidth() 106 || mHeight != buffer->getHeight(); 107 } 108 109 #if DEBUG_RENDERER 110 if (dropCounter > 0) { 111 RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); 112 } 113 #endif 114 mSurfaceTexture->getTransformMatrix(transform); 115 GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); 116 117 LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight, 118 !mBlend, forceFilter, renderTarget, transform); 119 } 120} 121 122} /* namespace uirenderer */ 123} /* namespace android */ 124