DeferredLayerUpdater.cpp revision 68bfe0a37a0dcef52abd81688d8520c5d16e1a85
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "DeferredLayerUpdater.h"
17
18#include "OpenGLRenderer.h"
19
20#include "LayerRenderer.h"
21
22namespace android {
23namespace uirenderer {
24
25static void defaultLayerDestroyer(Layer* layer) {
26    Caches::getInstance().resourceCache.decrementRefcount(layer);
27}
28
29DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer)
30        : mSurfaceTexture(0)
31        , mTransform(0)
32        , mNeedsGLContextAttach(false)
33        , mUpdateTexImage(false)
34        , mLayer(layer)
35        , mCaches(Caches::getInstance())
36        , mDestroyer(destroyer) {
37    mWidth = mLayer->layer.getWidth();
38    mHeight = mLayer->layer.getHeight();
39    mBlend = mLayer->isBlend();
40    mColorFilter = SkSafeRef(mLayer->getColorFilter());
41    mAlpha = mLayer->getAlpha();
42    mMode = mLayer->getMode();
43
44    if (!mDestroyer) {
45        mDestroyer = defaultLayerDestroyer;
46    }
47}
48
49DeferredLayerUpdater::~DeferredLayerUpdater() {
50    SkSafeUnref(mColorFilter);
51    setTransform(0);
52    mDestroyer(mLayer);
53}
54
55void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
56    OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode);
57    SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL;
58    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
59}
60
61bool DeferredLayerUpdater::apply() {
62    bool success = true;
63    // These properties are applied the same to both layer types
64    mLayer->setColorFilter(mColorFilter);
65    mLayer->setAlpha(mAlpha, mMode);
66
67    if (mSurfaceTexture.get()) {
68        if (mNeedsGLContextAttach) {
69            mNeedsGLContextAttach = false;
70            mSurfaceTexture->attachToContext(mLayer->getTexture());
71        }
72        if (mUpdateTexImage) {
73            mUpdateTexImage = false;
74            doUpdateTexImage();
75        }
76        if (mTransform) {
77            mLayer->getTransform().load(*mTransform);
78            setTransform(0);
79        }
80    }
81    return success;
82}
83
84void DeferredLayerUpdater::doUpdateTexImage() {
85    if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
86        float transform[16];
87
88        int64_t frameNumber = mSurfaceTexture->getFrameNumber();
89        // If the GLConsumer queue is in synchronous mode, need to discard all
90        // but latest frame, using the frame number to tell when we no longer
91        // have newer frames to target. Since we can't tell which mode it is in,
92        // do this unconditionally.
93        int dropCounter = 0;
94        while (mSurfaceTexture->updateTexImage() == NO_ERROR) {
95            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber();
96            if (newFrameNumber == frameNumber) break;
97            frameNumber = newFrameNumber;
98            dropCounter++;
99        }
100
101        bool forceFilter = false;
102        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
103        if (buffer != NULL) {
104            // force filtration if buffer size != layer size
105            forceFilter = mWidth != buffer->getWidth()
106                    || mHeight != buffer->getHeight();
107        }
108
109        #if DEBUG_RENDERER
110        if (dropCounter > 0) {
111            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
112        }
113        #endif
114        mSurfaceTexture->getTransformMatrix(transform);
115        GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
116
117        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
118                !mBlend, forceFilter, renderTarget, transform);
119    }
120}
121
122} /* namespace uirenderer */
123} /* namespace android */
124