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 "renderstate/RenderState.h" 19 #include "utils/PaintUtils.h" 20 21 namespace android { 22 namespace uirenderer { 23 24 DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState) 25 : mRenderState(renderState) 26 , mBlend(false) 27 , mSurfaceTexture(nullptr) 28 , mTransform(nullptr) 29 , mGLContextAttached(false) 30 , mUpdateTexImage(false) 31 , mLayer(nullptr) { 32 renderState.registerContextCallback(this); 33 } 34 35 DeferredLayerUpdater::~DeferredLayerUpdater() { 36 setTransform(nullptr); 37 mRenderState.removeContextCallback(this); 38 destroyLayer(); 39 } 40 41 void DeferredLayerUpdater::onContextDestroyed() { 42 destroyLayer(); 43 } 44 45 void DeferredLayerUpdater::destroyLayer() { 46 if (!mLayer) { 47 return; 48 } 49 50 if (mSurfaceTexture.get() && mGLContextAttached) { 51 mSurfaceTexture->detachFromView(); 52 mGLContextAttached = false; 53 } 54 55 mLayer->postDecStrong(); 56 57 mLayer = nullptr; 58 } 59 60 void DeferredLayerUpdater::setPaint(const SkPaint* paint) { 61 mAlpha = PaintUtils::getAlphaDirect(paint); 62 mMode = PaintUtils::getBlendModeDirect(paint); 63 if (paint) { 64 mColorFilter = paint->refColorFilter(); 65 } else { 66 mColorFilter.reset(); 67 } 68 } 69 70 void DeferredLayerUpdater::apply() { 71 if (!mLayer) { 72 mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode); 73 } 74 75 mLayer->setColorFilter(mColorFilter); 76 mLayer->setAlpha(mAlpha, mMode); 77 78 if (mSurfaceTexture.get()) { 79 if (!mGLContextAttached) { 80 mGLContextAttached = true; 81 mUpdateTexImage = true; 82 mSurfaceTexture->attachToView(); 83 } 84 if (mUpdateTexImage) { 85 mUpdateTexImage = false; 86 sk_sp<SkImage> layerImage; 87 SkMatrix textureTransform; 88 bool queueEmpty = true; 89 // If the SurfaceTexture queue is in synchronous mode, need to discard all 90 // but latest frame. Since we can't tell which mode it is in, 91 // do this unconditionally. 92 do { 93 layerImage = mSurfaceTexture->dequeueImage(textureTransform, &queueEmpty, 94 mRenderState); 95 } while (layerImage.get() && (!queueEmpty)); 96 if (layerImage.get()) { 97 // force filtration if buffer size != layer size 98 bool forceFilter = mWidth != layerImage->width() || mHeight != layerImage->height(); 99 updateLayer(forceFilter, textureTransform, layerImage); 100 } 101 } 102 103 if (mTransform) { 104 mLayer->getTransform() = *mTransform; 105 setTransform(nullptr); 106 } 107 } 108 } 109 110 void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform, 111 const sk_sp<SkImage>& layerImage) { 112 mLayer->setBlend(mBlend); 113 mLayer->setForceFilter(forceFilter); 114 mLayer->setSize(mWidth, mHeight); 115 mLayer->getTexTransform() = textureTransform; 116 mLayer->setImage(layerImage); 117 } 118 119 void DeferredLayerUpdater::detachSurfaceTexture() { 120 if (mSurfaceTexture.get()) { 121 destroyLayer(); 122 mSurfaceTexture = nullptr; 123 } 124 } 125 126 } /* namespace uirenderer */ 127 } /* namespace android */ 128