DeferredLayerUpdater.cpp revision 04fc583c3dd3144bc6b718fcac4b3e1afdfdb067
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
2504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer)
2604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        : mDisplayList(0)
2704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mSurfaceTexture(0)
2804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mTransform(0)
2904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mNeedsGLContextAttach(false)
3004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mUpdateTexImage(false)
3104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mLayer(layer)
3204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mRenderer(renderer)
3304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        , mCaches(Caches::getInstance()) {
3404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mCaches.resourceCache.incrementRefcount(mLayer);
3504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mWidth = mLayer->layer.getWidth();
3604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mHeight = mLayer->layer.getHeight();
3704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mBlend = mLayer->isBlend();
3804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mColorFilter = mLayer->getColorFilter();
3904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mAlpha = mLayer->getAlpha();
4004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mMode = mLayer->getMode();
4104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDirtyRect.setEmpty();
4204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
4304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
4404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::~DeferredLayerUpdater() {
4504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    setColorFilter(NULL);
4604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mLayer) {
4704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mCaches.resourceCache.decrementRefcount(mLayer);
4804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
4904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    delete mRenderer;
5004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
5104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
5204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::setColorFilter(SkColorFilter* colorFilter) {
5304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
5404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
5504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
5604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::setDisplayList(DisplayList* displayList,
5704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int left, int top, int right, int bottom) {
5804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDisplayList = displayList;
5904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mDirtyRect.isEmpty()) {
6004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.set(left, top, right, bottom);
6104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    } else {
6204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.unionWith(Rect(left, top, right, bottom));
6304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
6404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
6504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
6604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckbool DeferredLayerUpdater::apply() {
6704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    bool success = true;
6804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    // These properties are applied the same to both layer types
6904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setColorFilter(mColorFilter);
7004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setAlpha(mAlpha, mMode);
7104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
7204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mDisplayList) {
7304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mWidth != mLayer->layer.getWidth() || mHeight != mLayer->layer.getHeight()) {
7404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
7504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
7604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mLayer->setBlend(mBlend);
7704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mLayer->updateDeferred(mRenderer, mDisplayList,
7804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck                mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
7904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.setEmpty();
8004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDisplayList = 0;
8104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    } else 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        }
11404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #if DEBUG_RENDERER
11504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (dropCounter > 0) {
11604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
11704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
11804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #endif
11904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mSurfaceTexture->getTransformMatrix(transform);
12004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
12104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
12204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight, !mBlend,
12304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck                renderTarget, transform);
12404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
12504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
12604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
12704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::applyDeferred(DeferredLayerUpdater* deferredApply) {
12804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    // Default assignment operator doesn't quite work, and fails due to mCaches anyway
12904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mWidth = mWidth;
13004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mHeight = mHeight;
13104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mBlend = mBlend;
13204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mAlpha = mAlpha;
13304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mMode = mMode;
13404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mDirtyRect.set(mDirtyRect);
13504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mDisplayList = mDisplayList;
13604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mSurfaceTexture = mSurfaceTexture;
13704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mNeedsGLContextAttach = mNeedsGLContextAttach;
13804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->mUpdateTexImage = mUpdateTexImage;
13904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->setColorFilter(mColorFilter);
14004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    deferredApply->setTransform(mTransform);
14104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
14204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDisplayList = 0;
14304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDirtyRect.setEmpty();
14404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mTransform = 0;
14504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mNeedsGLContextAttach = false;
14604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mUpdateTexImage = false;
14704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
14804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
14904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */
15004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */
151