blob: 8e99b9a8cba7b29150720593ae6e98c1165a36c6 [file] [log] [blame]
John Reck04fc5832014-02-05 16:38:25 -08001/*
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
John Reckd72e0a32014-05-29 18:56:11 -070025static void defaultLayerDestroyer(Layer* layer) {
26 Caches::getInstance().resourceCache.decrementRefcount(layer);
27}
28
29DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer)
John Reck25fbb3f2014-06-12 13:46:45 -070030 : mSurfaceTexture(0)
John Reck04fc5832014-02-05 16:38:25 -080031 , mTransform(0)
32 , mNeedsGLContextAttach(false)
33 , mUpdateTexImage(false)
34 , mLayer(layer)
John Reckd72e0a32014-05-29 18:56:11 -070035 , mCaches(Caches::getInstance())
36 , mDestroyer(destroyer) {
John Reck04fc5832014-02-05 16:38:25 -080037 mWidth = mLayer->layer.getWidth();
38 mHeight = mLayer->layer.getHeight();
39 mBlend = mLayer->isBlend();
Derek Sollenberger674554f2014-02-19 16:47:32 +000040 mColorFilter = SkSafeRef(mLayer->getColorFilter());
John Reck04fc5832014-02-05 16:38:25 -080041 mAlpha = mLayer->getAlpha();
42 mMode = mLayer->getMode();
John Reckd72e0a32014-05-29 18:56:11 -070043
44 if (!mDestroyer) {
45 mDestroyer = defaultLayerDestroyer;
46 }
John Reck04fc5832014-02-05 16:38:25 -080047}
48
49DeferredLayerUpdater::~DeferredLayerUpdater() {
Derek Sollenberger674554f2014-02-19 16:47:32 +000050 SkSafeUnref(mColorFilter);
John Reck8ca3eec2014-04-10 10:28:45 -070051 setTransform(0);
John Reckd72e0a32014-05-29 18:56:11 -070052 mDestroyer(mLayer);
John Reck04fc5832014-02-05 16:38:25 -080053}
54
Derek Sollenberger674554f2014-02-19 16:47:32 +000055void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
56 OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode);
57 SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL;
John Reck04fc5832014-02-05 16:38:25 -080058 SkRefCnt_SafeAssign(mColorFilter, colorFilter);
59}
60
John Reck860d1552014-04-11 19:15:05 -070061bool DeferredLayerUpdater::apply(TreeInfo& info) {
John Reck04fc5832014-02-05 16:38:25 -080062 bool success = true;
63 // These properties are applied the same to both layer types
64 mLayer->setColorFilter(mColorFilter);
65 mLayer->setAlpha(mAlpha, mMode);
66
John Reck25fbb3f2014-06-12 13:46:45 -070067 if (mSurfaceTexture.get()) {
John Reck04fc5832014-02-05 16:38:25 -080068 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 }
Chris Craik9757ac02014-02-25 18:50:17 -0800100
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
John Reck04fc5832014-02-05 16:38:25 -0800109 #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
Chris Craik9757ac02014-02-25 18:50:17 -0800117 LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
118 !mBlend, forceFilter, renderTarget, transform);
John Reck04fc5832014-02-05 16:38:25 -0800119 }
120}
121
John Reck04fc5832014-02-05 16:38:25 -0800122} /* namespace uirenderer */
123} /* namespace android */