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