DeferredLayerUpdater.cpp revision 749906b468912dab7bf69a86e852deac3e80b0cc
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 1804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck#include "OpenGLRenderer.h" 1904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 2004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck#include "LayerRenderer.h" 21749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck#include "renderthread/EglManager.h" 22749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck#include "renderthread/RenderTask.h" 2304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 2404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace android { 2504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace uirenderer { 2604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 27749906b468912dab7bf69a86e852deac3e80b0ccJohn Reckclass DeleteLayerTask : public renderthread::RenderTask { 28749906b468912dab7bf69a86e852deac3e80b0ccJohn Reckpublic: 29749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck DeleteLayerTask(renderthread::EglManager& eglManager, Layer* layer) 30749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck : mEglManager(eglManager) 31749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck , mLayer(layer) 32749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck {} 33749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck 34749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck virtual void run() { 35749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck mEglManager.requireGlContext(); 36749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck LayerRenderer::destroyLayer(mLayer); 37749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck mLayer = 0; 38749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck delete this; 39749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck } 40d72e0a339b54af0c4e731513bbad120dff694723John Reck 41749906b468912dab7bf69a86e852deac3e80b0ccJohn Reckprivate: 42749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck renderthread::EglManager& mEglManager; 43749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck Layer* mLayer; 44749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck}; 45749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck 46749906b468912dab7bf69a86e852deac3e80b0ccJohn ReckDeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer) 4725fbb3fa1138675379102a44405852555cefccbdJohn Reck : mSurfaceTexture(0) 4804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck , mTransform(0) 4904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck , mNeedsGLContextAttach(false) 5004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck , mUpdateTexImage(false) 5104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck , mLayer(layer) 52d72e0a339b54af0c4e731513bbad120dff694723John Reck , mCaches(Caches::getInstance()) 53749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck , mRenderThread(thread) { 5404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mWidth = mLayer->layer.getWidth(); 5504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mHeight = mLayer->layer.getHeight(); 5604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mBlend = mLayer->isBlend(); 57674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger mColorFilter = SkSafeRef(mLayer->getColorFilter()); 5804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mAlpha = mLayer->getAlpha(); 5904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mMode = mLayer->getMode(); 6004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 6104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 6204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::~DeferredLayerUpdater() { 63674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger SkSafeUnref(mColorFilter); 648ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reck setTransform(0); 65749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck mRenderThread.queue(new DeleteLayerTask(mRenderThread.eglManager(), mLayer)); 66749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck mLayer = 0; 6704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 6804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 69674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenbergervoid DeferredLayerUpdater::setPaint(const SkPaint* paint) { 70674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode); 71674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL; 7204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck SkRefCnt_SafeAssign(mColorFilter, colorFilter); 7304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 7404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 7568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckbool DeferredLayerUpdater::apply() { 7604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck bool success = true; 7704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // These properties are applied the same to both layer types 7804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->setColorFilter(mColorFilter); 7904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->setAlpha(mAlpha, mMode); 8004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 8125fbb3fa1138675379102a44405852555cefccbdJohn Reck if (mSurfaceTexture.get()) { 8204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mNeedsGLContextAttach) { 8304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mNeedsGLContextAttach = false; 8404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mSurfaceTexture->attachToContext(mLayer->getTexture()); 8504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 8604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mUpdateTexImage) { 8704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mUpdateTexImage = false; 8804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck doUpdateTexImage(); 8904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 9004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mTransform) { 9104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer->getTransform().load(*mTransform); 9204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck setTransform(0); 9304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 9404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 9504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck return success; 9604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 9704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 9804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::doUpdateTexImage() { 9904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (mSurfaceTexture->updateTexImage() == NO_ERROR) { 10004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck float transform[16]; 10104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 10204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int64_t frameNumber = mSurfaceTexture->getFrameNumber(); 10304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // If the GLConsumer queue is in synchronous mode, need to discard all 10404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // but latest frame, using the frame number to tell when we no longer 10504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // have newer frames to target. Since we can't tell which mode it is in, 10604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck // do this unconditionally. 10704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int dropCounter = 0; 10804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck while (mSurfaceTexture->updateTexImage() == NO_ERROR) { 10904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); 11004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (newFrameNumber == frameNumber) break; 11104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck frameNumber = newFrameNumber; 11204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck dropCounter++; 11304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 1149757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik 1159757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik bool forceFilter = false; 1169757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); 1179757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik if (buffer != NULL) { 1189757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik // force filtration if buffer size != layer size 1199757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik forceFilter = mWidth != buffer->getWidth() 1209757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik || mHeight != buffer->getHeight(); 1219757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik } 1229757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik 12304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck #if DEBUG_RENDERER 12404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck if (dropCounter > 0) { 12504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); 12604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 12704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck #endif 12804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mSurfaceTexture->getTransformMatrix(transform); 12904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); 13004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 1319757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight, 1329757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik !mBlend, forceFilter, renderTarget, transform); 13304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck } 13404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} 13504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck 136918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reckvoid DeferredLayerUpdater::detachSurfaceTexture() { 137918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck if (mSurfaceTexture.get()) { 138749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck mRenderThread.eglManager().requireGlContext(); 139749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck status_t err = mSurfaceTexture->detachFromContext(); 140749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck if (err != 0) { 141749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck // TODO: Elevate to fatal exception 142749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck ALOGE("Failed to detach SurfaceTexture from context %d", err); 143749906b468912dab7bf69a86e852deac3e80b0ccJohn Reck } 144918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck mSurfaceTexture = 0; 145918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck mLayer->clearTexture(); 146918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck } 147918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck} 148918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck 14904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */ 15004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */ 151