DeferredLayerUpdater.cpp revision 9757ac0b9d62f6aea5e47cfb375f445c78bb7897
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    mWidth = mLayer->layer.getWidth();
3504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mHeight = mLayer->layer.getHeight();
3604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mBlend = mLayer->isBlend();
37674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    mColorFilter = SkSafeRef(mLayer->getColorFilter());
3804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mAlpha = mLayer->getAlpha();
3904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mMode = mLayer->getMode();
4004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDirtyRect.setEmpty();
4104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
4204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
4304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John ReckDeferredLayerUpdater::~DeferredLayerUpdater() {
44674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    SkSafeUnref(mColorFilter);
4504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mLayer) {
4604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mCaches.resourceCache.decrementRefcount(mLayer);
4704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
4804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    delete mRenderer;
4904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
5004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
51674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenbergervoid DeferredLayerUpdater::setPaint(const SkPaint* paint) {
52674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode);
53674554fc36932ca50b15bba41ac6f650254d4e72Derek Sollenberger    SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL;
5404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
5504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
5604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
5704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::setDisplayList(DisplayList* displayList,
5804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int left, int top, int right, int bottom) {
5904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mDisplayList = displayList;
6004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mDirtyRect.isEmpty()) {
6104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.set(left, top, right, bottom);
6204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    } else {
6304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.unionWith(Rect(left, top, right, bottom));
6404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
6504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
6604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
6704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckbool DeferredLayerUpdater::apply() {
6804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    bool success = true;
6904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    // These properties are applied the same to both layer types
7004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setColorFilter(mColorFilter);
7104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    mLayer->setAlpha(mAlpha, mMode);
7204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
7304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mDisplayList) {
7404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mWidth != mLayer->layer.getWidth() || mHeight != mLayer->layer.getHeight()) {
7504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
7604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
7704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mLayer->setBlend(mBlend);
7804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mLayer->updateDeferred(mRenderer, mDisplayList,
7904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck                mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
8004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDirtyRect.setEmpty();
8104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mDisplayList = 0;
8204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    } else if (mSurfaceTexture.get()) {
8304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mNeedsGLContextAttach) {
8404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mNeedsGLContextAttach = false;
8504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mSurfaceTexture->attachToContext(mLayer->getTexture());
8604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
8704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mUpdateTexImage) {
8804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mUpdateTexImage = false;
8904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            doUpdateTexImage();
9004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
9104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (mTransform) {
9204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            mLayer->getTransform().load(*mTransform);
9304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            setTransform(0);
9404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
9504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
9604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    return success;
9704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
9804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
9904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckvoid DeferredLayerUpdater::doUpdateTexImage() {
10004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
10104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        float transform[16];
10204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
10304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int64_t frameNumber = mSurfaceTexture->getFrameNumber();
10404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // If the GLConsumer queue is in synchronous mode, need to discard all
10504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // but latest frame, using the frame number to tell when we no longer
10604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // have newer frames to target. Since we can't tell which mode it is in,
10704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        // do this unconditionally.
10804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        int dropCounter = 0;
10904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        while (mSurfaceTexture->updateTexImage() == NO_ERROR) {
11004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber();
11104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            if (newFrameNumber == frameNumber) break;
11204fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            frameNumber = newFrameNumber;
11304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            dropCounter++;
11404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
1159757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
1169757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        bool forceFilter = false;
1179757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
1189757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        if (buffer != NULL) {
1199757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik            // force filtration if buffer size != layer size
1209757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik            forceFilter = mWidth != buffer->getWidth()
1219757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik                    || mHeight != buffer->getHeight();
1229757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        }
1239757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik
12404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #if DEBUG_RENDERER
12504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        if (dropCounter > 0) {
12604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
12704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        }
12804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        #endif
12904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        mSurfaceTexture->getTransformMatrix(transform);
13004fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck        GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
13104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
1329757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
1339757ac0b9d62f6aea5e47cfb375f445c78bb7897Chris Craik                !mBlend, forceFilter, renderTarget, transform);
13404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    }
13504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck}
13604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck
13704fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace uirenderer */
13804fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck} /* namespace android */
139