DeferredLayerUpdater.cpp revision 918ad523b2780e0c893f3d2a32d4ec13f2a7e921
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"
2104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
2204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace android {
2304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Recknamespace uirenderer {
2404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
25d72e0a339b54af0c4e731513bbad120dff694723John Reckstatic void defaultLayerDestroyer(Layer* layer) {
26d72e0a339b54af0c4e731513bbad120dff694723John Reck    Caches::getInstance().resourceCache.decrementRefcount(layer);
27d72e0a339b54af0c4e731513bbad120dff694723John Reck}
28d72e0a339b54af0c4e731513bbad120dff694723John Reck
29d72e0a339b54af0c4e731513bbad120dff694723John ReckDeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer)
3025fbb3fa1138675379102a44405852555cefccbdJohn Reck        : mSurfaceTexture(0)
3104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mTransform(0)
3204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mNeedsGLContextAttach(false)
3304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mUpdateTexImage(false)
3404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mLayer(layer)
35d72e0a339b54af0c4e731513bbad120dff694723John Reck        , mCaches(Caches::getInstance())
36d72e0a339b54af0c4e731513bbad120dff694723John Reck        , mDestroyer(destroyer) {
3704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mWidth = mLayer->layer.getWidth();
3804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mHeight = mLayer->layer.getHeight();
3904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mBlend = mLayer->isBlend();
40674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    mColorFilter = SkSafeRef(mLayer->getColorFilter());
4104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mAlpha = mLayer->getAlpha();
4204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mMode = mLayer->getMode();
43d72e0a339b54af0c4e731513bbad120dff694723John Reck
44d72e0a339b54af0c4e731513bbad120dff694723John Reck    if (!mDestroyer) {
45d72e0a339b54af0c4e731513bbad120dff694723John Reck        mDestroyer = defaultLayerDestroyer;
46d72e0a339b54af0c4e731513bbad120dff694723John Reck    }
4704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
4804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
4904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::~DeferredLayerUpdater() {
50674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    SkSafeUnref(mColorFilter);
518ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reck    setTransform(0);
52d72e0a339b54af0c4e731513bbad120dff694723John Reck    mDestroyer(mLayer);
5304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
5404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
55674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenbergervoid DeferredLayerUpdater::setPaint(const SkPaint* paint) {
56674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode);
57674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL;
5804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
5904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
6004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
6168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckbool DeferredLayerUpdater::apply() {
6204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    bool success = true;
6304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    // These properties are applied the same to both layer types
6404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setColorFilter(mColorFilter);
6504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setAlpha(mAlpha, mMode);
6604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
6725fbb3fa1138675379102a44405852555cefccbdJohn Reck    if (mSurfaceTexture.get()) {
6804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mNeedsGLContextAttach) {
6904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mNeedsGLContextAttach = false;
7004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mSurfaceTexture->attachToContext(mLayer->getTexture());
7104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
7204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mUpdateTexImage) {
7304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mUpdateTexImage = false;
7404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            doUpdateTexImage();
7504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
7604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mTransform) {
7704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mLayer->getTransform().load(*mTransform);
7804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            setTransform(0);
7904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
8004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
8104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    return success;
8204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
8304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
8404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::doUpdateTexImage() {
8504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
8604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        float transform[16];
8704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
8804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int64_t frameNumber = mSurfaceTexture->getFrameNumber();
8904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // If the GLConsumer queue is in synchronous mode, need to discard all
9004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // but latest frame, using the frame number to tell when we no longer
9104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // have newer frames to target. Since we can't tell which mode it is in,
9204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // do this unconditionally.
9304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int dropCounter = 0;
9404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        while (mSurfaceTexture->updateTexImage() == NO_ERROR) {
9504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber();
9604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            if (newFrameNumber == frameNumber) break;
9704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            frameNumber = newFrameNumber;
9804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            dropCounter++;
9904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
1009757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
1019757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        bool forceFilter = false;
1029757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
1039757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        if (buffer != NULL) {
1049757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik            // force filtration if buffer size != layer size
1059757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik            forceFilter = mWidth != buffer->getWidth()
1069757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik                    || mHeight != buffer->getHeight();
1079757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        }
1089757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
10904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #if DEBUG_RENDERER
11004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (dropCounter > 0) {
11104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
11204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
11304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #endif
11404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mSurfaceTexture->getTransformMatrix(transform);
11504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
11604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
1179757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
1189757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik                !mBlend, forceFilter, renderTarget, transform);
11904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
12004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
12104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
122918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reckvoid DeferredLayerUpdater::detachSurfaceTexture() {
123918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    if (mSurfaceTexture.get()) {
124918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        mSurfaceTexture->detachFromContext();
125918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        mSurfaceTexture = 0;
126918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        mLayer->clearTexture();
127918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    }
128918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck}
129918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck
13004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */
13104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */
132