Layer.cpp revision 19733a32799f792125913e746e8644d16f8dc223
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/compiler.h>
2599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <cutils/native_handle.h>
26076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/properties.h>
2799b49840d309727678b77403d6cc9f920111623fMathias Agopian
2899b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian#include <utils/StopWatch.h>
3199b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/Trace.h>
32375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/GraphicBuffer.h>
3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <ui/PixelFormat.h>
359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
367e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian#include <gui/Surface.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Colorizer.h"
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayDevice.h"
41f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "Layer.h"
42f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "SurfaceFlinger.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceTextureLayer.h"
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/HWComposer.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "RenderEngine/RenderEngine.h"
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#define DEBUG_RESIZE    0
50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
52b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
53118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian// ---------------------------------------------------------------------------
54a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint32_t Layer::sSequence = 1;
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   contentDirty(false),
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sequence(uint32_t(android_atomic_inc(&sSequence))),
6196f0819f81293076e652792794a961543e6750d7Mathias Agopian        mFlinger(flinger),
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTextureName(-1U),
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPremultipliedAlpha(true),
6496f0819f81293076e652792794a961543e6750d7Mathias Agopian        mName("unnamed"),
6596f0819f81293076e652792794a961543e6750d7Mathias Agopian        mDebug(false),
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFormat(PIXEL_FORMAT_NONE),
6796f0819f81293076e652792794a961543e6750d7Mathias Agopian        mOpaqueLayer(true),
6896f0819f81293076e652792794a961543e6750d7Mathias Agopian        mTransactionFlags(0),
6996f0819f81293076e652792794a961543e6750d7Mathias Agopian        mQueuedFrames(0),
704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian        mCurrentTransform(0),
71b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
7296f0819f81293076e652792794a961543e6750d7Mathias Agopian        mCurrentOpacity(true),
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mRefreshPending(false),
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFrameLatencyNeeded(false),
7596f0819f81293076e652792794a961543e6750d7Mathias Agopian        mFiltering(false),
7696f0819f81293076e652792794a961543e6750d7Mathias Agopian        mNeedsFiltering(false),
770ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
7896f0819f81293076e652792794a961543e6750d7Mathias Agopian        mSecure(false),
7996f0819f81293076e652792794a961543e6750d7Mathias Agopian        mProtectedByApp(false),
8096f0819f81293076e652792794a961543e6750d7Mathias Agopian        mHasSurface(false),
81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mClientRef(client)
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
8396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mCurrentCrop.makeInvalid();
844f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
85b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
864f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
874f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    uint32_t layerFlags = 0;
884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
894f113740180b6512b43723c4728f262882dc9b45Mathias Agopian        layerFlags = layer_state_t::eLayerHidden;
904f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
914f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
924f113740180b6512b43723c4728f262882dc9b45Mathias Agopian        mPremultipliedAlpha = false;
93b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
94b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mName = name;
959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.active.w = w;
979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.active.h = h;
989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.active.crop.makeInvalid();
999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.z = 0;
1009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.alpha = 0xFF;
101d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    mCurrentState.layerStack = 0;
1029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.flags = layerFlags;
1039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mCurrentState.sequence = 0;
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.transform.set(0, 0);
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.requested = mCurrentState.active;
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // drawing state & current state are identical
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t displayPeriod =
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onFirstRef() {
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mBufferQueue = new SurfaceTextureLayer(mFlinger);
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
1190d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
1202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
1212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mSurfaceFlingerConsumer->setName(mName);
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
12459119e658a12279e8fff508f8773843de2d90917Mathias Agopian#warning "disabling triple buffering"
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#else
127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    updateTransformHint(hw);
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias AgopianLayer::~Layer() {
1350d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    sp<Client> c(mClientRef.promote());
1362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (c != 0) {
1372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        c->detachLayer(this);
1382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
1392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameTracker.logAndResetStats(mName);
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// callbacks
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        HWComposer::HWCLayerInterface* layer) {
149a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian    if (layer) {
150a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian        layer->onDisplayed();
151a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
1521f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
153a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian}
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onFrameAvailable() {
156a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian    android_atomic_inc(&mQueuedFrames);
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFlinger->signalLayerUpdate();
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// called with SurfaceFlinger::mStateLock from the drawing thread after
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// the layer has been remove from the current state list (and just before
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// it's removed from the drawing state list)
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onRemoved() {
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurfaceFlingerConsumer->abandon();
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1687e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian// set-up
1699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
1707303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst String8& Layer::getName() const {
172b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    return mName;
17328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis}
174c08731e756868653d09d3e49b723706df3687070Mathias Agopian
175582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
176d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian                            PixelFormat format, uint32_t flags)
177bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian{
178bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian    uint32_t const maxSurfaceDims = min(
179bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
180bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian
181bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian    // never allow a surface larger than what our underlying GL implementation
182bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian    // can handle.
183bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
18459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
1859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return BAD_VALUE;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFormat = format;
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
191118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
1924a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
1934a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
194118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
195118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
196118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
197118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
198118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
199118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return NO_ERROR;
200118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
201076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
202076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<IBinder> Layer::getHandle() {
203076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
204ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
205b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
206b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "Layer::getHandle() has already been called");
207b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    mHasSurface = true;
2099575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
210118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    /*
211118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     * The layer handle is just a BBinder object passed to the client
212118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
213118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     * the dtor is called when the remote side let go of its reference.
214118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     *
215118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
216118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     * this layer when the handle is destroyed.
217118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian     */
218118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
219118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
220118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        wp<const Layer> mOwner;
221118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    public:
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2231f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        }
2251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    };
2261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
22796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return new Handle(mFlinger, this);
228d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IGraphicBufferProducer> Layer::getBufferQueue() const {
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mBufferQueue;
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2330ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian
2347e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian// ---------------------------------------------------------------------------
2350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian// h/w composer set-up
2360ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian// ---------------------------------------------------------------------------
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect Layer::getContentCrop() const {
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this is the crop rectangle that applies to the buffer
240b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // itself (as opposed to the window)
241f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    Rect crop;
24296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (!mCurrentCrop.isEmpty()) {
2431c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        // if the buffer crop is defined, we use that
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        crop = mCurrentCrop;
245b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } else if (mActiveBuffer != NULL) {
246f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        // otherwise we use the whole buffer
24796f0819f81293076e652792794a961543e6750d7Mathias Agopian        crop = mActiveBuffer->getBounds();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
249118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
250118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        crop.makeInvalid();
251118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    }
252118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return crop;
25396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
254ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (CC_LIKELY(exclude.isEmpty())) {
257f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian        return win;
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
259f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    if (exclude.isRect()) {
260f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian        return win.reduce(exclude.getBounds());
261f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    }
262f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    return Region(win).subtract(exclude).getBounds();
263f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian}
264f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian
265f6679fc6f70939643901f29a9a69e40c603e6e5fMathias AgopianRect Layer::computeBounds() const {
266f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    const Layer::State& s(getDrawingState());
267f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    Rect win(s.active.w, s.active.h);
268f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    if (!s.active.crop.isEmpty()) {
269f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian        win.intersect(s.active.crop, &win);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // subtract the transparent region and snap to the bounds
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return reduce(win, s.activeTransparentRegion);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the content crop is the area of the content that gets scaled to the
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // layer's size.
27821230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown    FloatRect crop(getContentCrop());
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the active.crop is the area of the window that gets cropped, but not
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // scaled in any ways.
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const State& s(getDrawingState());
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // apply the projection's clipping to the window crop in
285550a11455a5155b078085fd5f464d7f3e5dfb7fcAndy McFadden    // layerstack space, and convert-back to layer space.
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // if there are no window scaling involved, this operation will map to full
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // pixels in the buffer.
288e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
289e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2912944a2b3601ae5847cf54b3130dcf653a7b24b8aAndy McFadden    Rect activeCrop(s.active.w, s.active.h);
292e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian    if (!s.active.crop.isEmpty()) {
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        activeCrop = s.active.crop;
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
295ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    activeCrop = s.transform.transform(activeCrop);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    activeCrop.intersect(hw->getViewport(), &activeCrop);
2981bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // paranoia: make sure the window-crop is constrained in the
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // window's bounds
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // subtract the transparent region and snap to the bounds
305a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!activeCrop.isEmpty()) {
3089c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Transform the window crop to match the buffer coordinate system,
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // which means using the inverse of the current transform set on the
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // SurfaceFlingerConsumer.
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t invTransform = mCurrentTransform;
3120dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian        int winWidth = s.active.w;
3130dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian        int winHeight = s.active.h;
3140dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
31596f0819f81293076e652792794a961543e6750d7Mathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
31696f0819f81293076e652792794a961543e6750d7Mathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
317076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            winWidth = s.active.h;
318076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            winHeight = s.active.w;
3199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        }
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Rect winCrop = activeCrop.transform(
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                invTransform, s.active.w, s.active.h);
322dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
323bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        float xScale = crop.getWidth()  / float(winWidth);
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        float yScale = crop.getHeight() / float(winHeight);
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        float insetL = winCrop.left                 * xScale;
32874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        float insetT = winCrop.top                  * yScale;
32974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
331bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian
33274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        crop.left   += insetL;
333abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        crop.top    += insetT;
334abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        crop.right  -= insetR;
3359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        crop.bottom -= insetB;
3369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
33759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return crop;
338d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
339d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
340d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianvoid Layer::setGeometry(
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<const DisplayDevice>& hw,
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        HWComposer::HWCLayerInterface& layer)
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer.setDefaultState();
345f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
346f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // enable this layer
347bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    layer.setSkip(false);
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (isSecure() && !hw->isSecure()) {
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer.setSkip(true);
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // this gives us only the "orientation" component of the transform
35428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    const State& s(getDrawingState());
35596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (!isOpaque() || s.alpha != 0xFF) {
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer.setBlending(mPremultipliedAlpha ?
35796f0819f81293076e652792794a961543e6750d7Mathias Agopian                HWC_BLENDING_PREMULT :
35896f0819f81293076e652792794a961543e6750d7Mathias Agopian                HWC_BLENDING_COVERAGE);
359b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3610dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    // apply the layer's transform, followed by the display's global transform
3620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    // here we're guaranteed that the layer's transform preserves rects
3630dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Rect frame(s.transform.transform(computeBounds()));
3640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    frame.intersect(hw->getViewport(), &frame);
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& tr(hw->getTransform());
3667303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    layer.setFrame(tr.transform(frame));
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer.setCrop(computeCrop(hw));
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer.setPlaneAlpha(s.alpha);
3699575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
371d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian     * Transformations are applied in this order:
37299b49840d309727678b77403d6cc9f920111623fMathias Agopian     * 1) buffer orientation/flip/mirror
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * 2) state transformation (window manager)
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * 3) layer orientation (screen orientation)
3751bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
377970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
3780656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform transform(tr * s.transform * bufferOrientation);
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
381a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // this gives us only the "orientation" component of the transform
382abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    const uint32_t orientation = transform.getOrientation();
3834da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    if (orientation & Transform::ROT_INVALID) {
3844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // we can only handle simple transformation
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer.setSkip(true);
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer.setTransform(orientation);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}
39073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
391a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
3929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
3939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian    // we have to set the visible region on every frame because
3949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian    // we currently free it during onLayerDisplayed(), which is called
3959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian    // after HWComposer::commit() -- every frame.
3963330b203039dea366d4981db1408a460134b2d2cMathias Agopian    // Apply this display's projection's viewport to the visible region
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // before giving it to the HWC HAL.
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& tr = hw->getTransform();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer.setVisibleRegionScreen(visible);
401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // layer yet, or if we ran out of memory
404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    layer.setBuffer(mActiveBuffer);
405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian}
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        HWComposer::HWCLayerInterface& layer) {
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int fenceFd = -1;
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: there is a possible optimization here: we only need to set the
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // acquire fence the first time a new buffer is acquired on EACH display.
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layer.getCompositionType() == HWC_OVERLAY) {
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (fence->isValid()) {
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            fenceFd = fence->dup();
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (fenceFd == -1) {
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
421        }
422    }
423    layer.setAcquireFenceFd(fenceFd);
424}
425
426// ---------------------------------------------------------------------------
427// drawing...
428// ---------------------------------------------------------------------------
429
430void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
431    onDraw(hw, clip);
432}
433
434void Layer::draw(const sp<const DisplayDevice>& hw) {
435    onDraw( hw, Region(hw->bounds()) );
436}
437
438void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
439{
440    ATRACE_CALL();
441
442    if (CC_UNLIKELY(mActiveBuffer == 0)) {
443        // the texture has not been created yet, this Layer has
444        // in fact never been drawn into. This happens frequently with
445        // SurfaceView because the WindowManager can't know when the client
446        // has drawn the first time.
447
448        // If there is nothing under us, we paint the screen in black, otherwise
449        // we just skip this update.
450
451        // figure out if there is something below us
452        Region under;
453        const SurfaceFlinger::LayerVector& drawingLayers(
454                mFlinger->mDrawingState.layersSortedByZ);
455        const size_t count = drawingLayers.size();
456        for (size_t i=0 ; i<count ; ++i) {
457            const sp<Layer>& layer(drawingLayers[i]);
458            if (layer.get() == static_cast<Layer const*>(this))
459                break;
460            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
461        }
462        // if not everything below us is covered, we plug the holes!
463        Region holes(clip.subtract(under));
464        if (!holes.isEmpty()) {
465            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
466        }
467        return;
468    }
469
470    // Bind the current buffer to the GL texture, and wait for it to be
471    // ready for us to draw into.
472    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
473    if (err != NO_ERROR) {
474        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
475        // Go ahead and draw the buffer anyway; no matter what we do the screen
476        // is probably going to have something visibly wrong.
477    }
478
479    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
480
481    RenderEngine& engine(mFlinger->getRenderEngine());
482
483    if (!blackOutLayer) {
484        // TODO: we could be more subtle with isFixedSize()
485        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
486
487        // Query the texture matrix given our current filtering mode.
488        float textureMatrix[16];
489        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
490        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
491
492        // Set things up for texturing.
493        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
494        mTexture.setFiltering(useFiltering);
495        mTexture.setMatrix(textureMatrix);
496
497        engine.setupLayerTexturing(mTexture);
498    } else {
499        engine.setupLayerBlackedOut();
500    }
501    drawWithOpenGL(hw, clip);
502    engine.disableTexturing();
503}
504
505
506void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
507        float red, float green, float blue, float alpha) const
508{
509    RenderEngine& engine(mFlinger->getRenderEngine());
510    computeGeometry(hw, mMesh);
511    engine.setupFillWithColor(red, green, blue, alpha);
512    engine.drawMesh(mMesh);
513}
514
515void Layer::clearWithOpenGL(
516        const sp<const DisplayDevice>& hw, const Region& clip) const {
517    clearWithOpenGL(hw, clip, 0,0,0,0);
518}
519
520void Layer::drawWithOpenGL(
521        const sp<const DisplayDevice>& hw, const Region& clip) const {
522    const uint32_t fbHeight = hw->getHeight();
523    const State& s(getDrawingState());
524
525    computeGeometry(hw, mMesh);
526
527    /*
528     * NOTE: the way we compute the texture coordinates here produces
529     * different results than when we take the HWC path -- in the later case
530     * the "source crop" is rounded to texel boundaries.
531     * This can produce significantly different results when the texture
532     * is scaled by a large amount.
533     *
534     * The GL code below is more logical (imho), and the difference with
535     * HWC is due to a limitation of the HWC API to integers -- a question
536     * is suspend is wether we should ignore this problem or revert to
537     * GL composition when a buffer scaling is applied (maybe with some
538     * minimal value)? Or, we could make GL behave like HWC -- but this feel
539     * like more of a hack.
540     */
541    const Rect win(computeBounds());
542
543    float left   = float(win.left)   / float(s.active.w);
544    float top    = float(win.top)    / float(s.active.h);
545    float right  = float(win.right)  / float(s.active.w);
546    float bottom = float(win.bottom) / float(s.active.h);
547
548    // TODO: we probably want to generate the texture coords with the mesh
549    // here we assume that we only have 4 vertices
550    Mesh::VertexArray texCoords(mMesh.getTexCoordArray());
551    texCoords[0].s = left;
552    texCoords[0].t = 1.0f - top;
553    texCoords[1].s = left;
554    texCoords[1].t = 1.0f - bottom;
555    texCoords[2].s = right;
556    texCoords[2].t = 1.0f - bottom;
557    texCoords[3].s = right;
558    texCoords[3].t = 1.0f - top;
559
560    RenderEngine& engine(mFlinger->getRenderEngine());
561    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
562    engine.drawMesh(mMesh);
563    engine.disableBlending();
564}
565
566void Layer::setFiltering(bool filtering) {
567    mFiltering = filtering;
568}
569
570bool Layer::getFiltering() const {
571    return mFiltering;
572}
573
574// As documented in libhardware header, formats in the range
575// 0x100 - 0x1FF are specific to the HAL implementation, and
576// are known to have no alpha channel
577// TODO: move definition for device-specific range into
578// hardware.h, instead of using hard-coded values here.
579#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
580
581bool Layer::getOpacityForFormat(uint32_t format) {
582    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
583        return true;
584    }
585    switch (format) {
586        case HAL_PIXEL_FORMAT_RGBA_8888:
587        case HAL_PIXEL_FORMAT_BGRA_8888:
588        case HAL_PIXEL_FORMAT_sRGB_A_8888:
589            return false;
590    }
591    // in all other case, we have no blending (also for unknown formats)
592    return true;
593}
594
595// ----------------------------------------------------------------------------
596// local state
597// ----------------------------------------------------------------------------
598
599void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
600{
601    const Layer::State& s(getDrawingState());
602    const Transform tr(hw->getTransform() * s.transform);
603    const uint32_t hw_h = hw->getHeight();
604    Rect win(s.active.w, s.active.h);
605    if (!s.active.crop.isEmpty()) {
606        win.intersect(s.active.crop, &win);
607    }
608    // subtract the transparent region and snap to the bounds
609    win = reduce(win, s.activeTransparentRegion);
610
611    Mesh::VertexArray position(mesh.getPositionArray());
612    tr.transform(position[0], win.left,  win.top);
613    tr.transform(position[1], win.left,  win.bottom);
614    tr.transform(position[2], win.right, win.bottom);
615    tr.transform(position[3], win.right, win.top);
616    for (size_t i=0 ; i<4 ; i++) {
617        position[i].y = hw_h - position[i].y;
618    }
619}
620
621bool Layer::isOpaque() const
622{
623    // if we don't have a buffer yet, we're translucent regardless of the
624    // layer's opaque flag.
625    if (mActiveBuffer == 0) {
626        return false;
627    }
628
629    // if the layer has the opaque flag, then we're always opaque,
630    // otherwise we use the current buffer's format.
631    return mOpaqueLayer || mCurrentOpacity;
632}
633
634bool Layer::isProtected() const
635{
636    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
637    return (activeBuffer != 0) &&
638            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
639}
640
641bool Layer::isFixedSize() const {
642    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
643}
644
645bool Layer::isCropped() const {
646    return !mCurrentCrop.isEmpty();
647}
648
649bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
650    return mNeedsFiltering || hw->needsFiltering();
651}
652
653void Layer::setVisibleRegion(const Region& visibleRegion) {
654    // always called from main thread
655    this->visibleRegion = visibleRegion;
656}
657
658void Layer::setCoveredRegion(const Region& coveredRegion) {
659    // always called from main thread
660    this->coveredRegion = coveredRegion;
661}
662
663void Layer::setVisibleNonTransparentRegion(const Region&
664        setVisibleNonTransparentRegion) {
665    // always called from main thread
666    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
667}
668
669// ----------------------------------------------------------------------------
670// transaction
671// ----------------------------------------------------------------------------
672
673uint32_t Layer::doTransaction(uint32_t flags) {
674    ATRACE_CALL();
675
676    const Layer::State& s(getDrawingState());
677    const Layer::State& c(getCurrentState());
678
679    const bool sizeChanged = (c.requested.w != s.requested.w) ||
680                             (c.requested.h != s.requested.h);
681
682    if (sizeChanged) {
683        // the size changed, we need to ask our client to request a new buffer
684        ALOGD_IF(DEBUG_RESIZE,
685                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
686                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
687                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
688                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
689                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
690                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
691                c.active.w, c.active.h,
692                c.active.crop.left,
693                c.active.crop.top,
694                c.active.crop.right,
695                c.active.crop.bottom,
696                c.active.crop.getWidth(),
697                c.active.crop.getHeight(),
698                c.requested.w, c.requested.h,
699                c.requested.crop.left,
700                c.requested.crop.top,
701                c.requested.crop.right,
702                c.requested.crop.bottom,
703                c.requested.crop.getWidth(),
704                c.requested.crop.getHeight(),
705                s.active.w, s.active.h,
706                s.active.crop.left,
707                s.active.crop.top,
708                s.active.crop.right,
709                s.active.crop.bottom,
710                s.active.crop.getWidth(),
711                s.active.crop.getHeight(),
712                s.requested.w, s.requested.h,
713                s.requested.crop.left,
714                s.requested.crop.top,
715                s.requested.crop.right,
716                s.requested.crop.bottom,
717                s.requested.crop.getWidth(),
718                s.requested.crop.getHeight());
719
720        // record the new size, form this point on, when the client request
721        // a buffer, it'll get the new size.
722        mSurfaceFlingerConsumer->setDefaultBufferSize(
723                c.requested.w, c.requested.h);
724    }
725
726    if (!isFixedSize()) {
727
728        const bool resizePending = (c.requested.w != c.active.w) ||
729                                   (c.requested.h != c.active.h);
730
731        if (resizePending) {
732            // don't let Layer::doTransaction update the drawing state
733            // if we have a pending resize, unless we are in fixed-size mode.
734            // the drawing state will be updated only once we receive a buffer
735            // with the correct size.
736            //
737            // in particular, we want to make sure the clip (which is part
738            // of the geometry state) is latched together with the size but is
739            // latched immediately when no resizing is involved.
740
741            flags |= eDontUpdateGeometryState;
742        }
743    }
744
745    // always set active to requested, unless we're asked not to
746    // this is used by Layer, which special cases resizes.
747    if (flags & eDontUpdateGeometryState)  {
748    } else {
749        Layer::State& editCurrentState(getCurrentState());
750        editCurrentState.active = c.requested;
751    }
752
753    if (s.active != c.active) {
754        // invalidate and recompute the visible regions if needed
755        flags |= Layer::eVisibleRegion;
756    }
757
758    if (c.sequence != s.sequence) {
759        // invalidate and recompute the visible regions if needed
760        flags |= eVisibleRegion;
761        this->contentDirty = true;
762
763        // we may use linear filtering, if the matrix scales us
764        const uint8_t type = c.transform.getType();
765        mNeedsFiltering = (!c.transform.preserveRects() ||
766                (type >= Transform::SCALE));
767    }
768
769    // Commit the transaction
770    commitTransaction();
771    return flags;
772}
773
774void Layer::commitTransaction() {
775    mDrawingState = mCurrentState;
776}
777
778uint32_t Layer::getTransactionFlags(uint32_t flags) {
779    return android_atomic_and(~flags, &mTransactionFlags) & flags;
780}
781
782uint32_t Layer::setTransactionFlags(uint32_t flags) {
783    return android_atomic_or(flags, &mTransactionFlags);
784}
785
786bool Layer::setPosition(float x, float y) {
787    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
788        return false;
789    mCurrentState.sequence++;
790    mCurrentState.transform.set(x, y);
791    setTransactionFlags(eTransactionNeeded);
792    return true;
793}
794bool Layer::setLayer(uint32_t z) {
795    if (mCurrentState.z == z)
796        return false;
797    mCurrentState.sequence++;
798    mCurrentState.z = z;
799    setTransactionFlags(eTransactionNeeded);
800    return true;
801}
802bool Layer::setSize(uint32_t w, uint32_t h) {
803    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
804        return false;
805    mCurrentState.requested.w = w;
806    mCurrentState.requested.h = h;
807    setTransactionFlags(eTransactionNeeded);
808    return true;
809}
810bool Layer::setAlpha(uint8_t alpha) {
811    if (mCurrentState.alpha == alpha)
812        return false;
813    mCurrentState.sequence++;
814    mCurrentState.alpha = alpha;
815    setTransactionFlags(eTransactionNeeded);
816    return true;
817}
818bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
819    mCurrentState.sequence++;
820    mCurrentState.transform.set(
821            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
822    setTransactionFlags(eTransactionNeeded);
823    return true;
824}
825bool Layer::setTransparentRegionHint(const Region& transparent) {
826    mCurrentState.requestedTransparentRegion = transparent;
827    setTransactionFlags(eTransactionNeeded);
828    return true;
829}
830bool Layer::setFlags(uint8_t flags, uint8_t mask) {
831    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
832    if (mCurrentState.flags == newFlags)
833        return false;
834    mCurrentState.sequence++;
835    mCurrentState.flags = newFlags;
836    setTransactionFlags(eTransactionNeeded);
837    return true;
838}
839bool Layer::setCrop(const Rect& crop) {
840    if (mCurrentState.requested.crop == crop)
841        return false;
842    mCurrentState.sequence++;
843    mCurrentState.requested.crop = crop;
844    setTransactionFlags(eTransactionNeeded);
845    return true;
846}
847
848bool Layer::setLayerStack(uint32_t layerStack) {
849    if (mCurrentState.layerStack == layerStack)
850        return false;
851    mCurrentState.sequence++;
852    mCurrentState.layerStack = layerStack;
853    setTransactionFlags(eTransactionNeeded);
854    return true;
855}
856
857// ----------------------------------------------------------------------------
858// pageflip handling...
859// ----------------------------------------------------------------------------
860
861bool Layer::onPreComposition() {
862    mRefreshPending = false;
863    return mQueuedFrames > 0;
864}
865
866void Layer::onPostComposition() {
867    if (mFrameLatencyNeeded) {
868        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
869        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
870
871        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
872        if (frameReadyFence->isValid()) {
873            mFrameTracker.setFrameReadyFence(frameReadyFence);
874        } else {
875            // There was no fence for this frame, so assume that it was ready
876            // to be presented at the desired present time.
877            mFrameTracker.setFrameReadyTime(desiredPresentTime);
878        }
879
880        const HWComposer& hwc = mFlinger->getHwComposer();
881        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
882        if (presentFence->isValid()) {
883            mFrameTracker.setActualPresentFence(presentFence);
884        } else {
885            // The HWC doesn't support present fences, so use the refresh
886            // timestamp instead.
887            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
888            mFrameTracker.setActualPresentTime(presentTime);
889        }
890
891        mFrameTracker.advanceFrame();
892        mFrameLatencyNeeded = false;
893    }
894}
895
896bool Layer::isVisible() const {
897    const Layer::State& s(mDrawingState);
898    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
899            && (mActiveBuffer != NULL);
900}
901
902Region Layer::latchBuffer(bool& recomputeVisibleRegions)
903{
904    ATRACE_CALL();
905
906    Region outDirtyRegion;
907    if (mQueuedFrames > 0) {
908
909        // if we've already called updateTexImage() without going through
910        // a composition step, we have to skip this layer at this point
911        // because we cannot call updateTeximage() without a corresponding
912        // compositionComplete() call.
913        // we'll trigger an update in onPreComposition().
914        if (mRefreshPending) {
915            return outDirtyRegion;
916        }
917
918        // Capture the old state of the layer for comparisons later
919        const bool oldOpacity = isOpaque();
920        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
921
922        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
923            Layer::State& front;
924            Layer::State& current;
925            bool& recomputeVisibleRegions;
926            Reject(Layer::State& front, Layer::State& current,
927                    bool& recomputeVisibleRegions)
928                : front(front), current(current),
929                  recomputeVisibleRegions(recomputeVisibleRegions) {
930            }
931
932            virtual bool reject(const sp<GraphicBuffer>& buf,
933                    const IGraphicBufferConsumer::BufferItem& item) {
934                if (buf == NULL) {
935                    return false;
936                }
937
938                uint32_t bufWidth  = buf->getWidth();
939                uint32_t bufHeight = buf->getHeight();
940
941                // check that we received a buffer of the right size
942                // (Take the buffer's orientation into account)
943                if (item.mTransform & Transform::ROT_90) {
944                    swap(bufWidth, bufHeight);
945                }
946
947                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
948                if (front.active != front.requested) {
949
950                    if (isFixedSize ||
951                            (bufWidth == front.requested.w &&
952                             bufHeight == front.requested.h))
953                    {
954                        // Here we pretend the transaction happened by updating the
955                        // current and drawing states. Drawing state is only accessed
956                        // in this thread, no need to have it locked
957                        front.active = front.requested;
958
959                        // We also need to update the current state so that
960                        // we don't end-up overwriting the drawing state with
961                        // this stale current state during the next transaction
962                        //
963                        // NOTE: We don't need to hold the transaction lock here
964                        // because State::active is only accessed from this thread.
965                        current.active = front.active;
966
967                        // recompute visible region
968                        recomputeVisibleRegions = true;
969                    }
970
971                    ALOGD_IF(DEBUG_RESIZE,
972                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
973                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
974                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
975                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
976                            front.active.w, front.active.h,
977                            front.active.crop.left,
978                            front.active.crop.top,
979                            front.active.crop.right,
980                            front.active.crop.bottom,
981                            front.active.crop.getWidth(),
982                            front.active.crop.getHeight(),
983                            front.requested.w, front.requested.h,
984                            front.requested.crop.left,
985                            front.requested.crop.top,
986                            front.requested.crop.right,
987                            front.requested.crop.bottom,
988                            front.requested.crop.getWidth(),
989                            front.requested.crop.getHeight());
990                }
991
992                if (!isFixedSize) {
993                    if (front.active.w != bufWidth ||
994                        front.active.h != bufHeight) {
995                        // reject this buffer
996                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
997                        //        bufWidth, bufHeight, front.active.w, front.active.h);
998                        return true;
999                    }
1000                }
1001
1002                // if the transparent region has changed (this test is
1003                // conservative, but that's fine, worst case we're doing
1004                // a bit of extra work), we latch the new one and we
1005                // trigger a visible-region recompute.
1006                if (!front.activeTransparentRegion.isTriviallyEqual(
1007                        front.requestedTransparentRegion)) {
1008                    front.activeTransparentRegion = front.requestedTransparentRegion;
1009
1010                    // We also need to update the current state so that
1011                    // we don't end-up overwriting the drawing state with
1012                    // this stale current state during the next transaction
1013                    //
1014                    // NOTE: We don't need to hold the transaction lock here
1015                    // because State::active is only accessed from this thread.
1016                    current.activeTransparentRegion = front.activeTransparentRegion;
1017
1018                    // recompute visible region
1019                    recomputeVisibleRegions = true;
1020                }
1021
1022                return false;
1023            }
1024        };
1025
1026
1027        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
1028
1029        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1030        if (updateResult == BufferQueue::PRESENT_LATER) {
1031            // Producer doesn't want buffer to be displayed yet.  Signal a
1032            // layer update so we check again at the next opportunity.
1033            mFlinger->signalLayerUpdate();
1034            return outDirtyRegion;
1035        }
1036
1037        // Decrement the queued-frames count.  Signal another event if we
1038        // have more frames pending.
1039        if (android_atomic_dec(&mQueuedFrames) > 1) {
1040            mFlinger->signalLayerUpdate();
1041        }
1042
1043        if (updateResult != NO_ERROR) {
1044            // something happened!
1045            recomputeVisibleRegions = true;
1046            return outDirtyRegion;
1047        }
1048
1049        // update the active buffer
1050        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1051        if (mActiveBuffer == NULL) {
1052            // this can only happen if the very first buffer was rejected.
1053            return outDirtyRegion;
1054        }
1055
1056        mRefreshPending = true;
1057        mFrameLatencyNeeded = true;
1058        if (oldActiveBuffer == NULL) {
1059             // the first time we receive a buffer, we need to trigger a
1060             // geometry invalidation.
1061            recomputeVisibleRegions = true;
1062         }
1063
1064        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1065        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1066        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1067        if ((crop != mCurrentCrop) ||
1068            (transform != mCurrentTransform) ||
1069            (scalingMode != mCurrentScalingMode))
1070        {
1071            mCurrentCrop = crop;
1072            mCurrentTransform = transform;
1073            mCurrentScalingMode = scalingMode;
1074            recomputeVisibleRegions = true;
1075        }
1076
1077        if (oldActiveBuffer != NULL) {
1078            uint32_t bufWidth  = mActiveBuffer->getWidth();
1079            uint32_t bufHeight = mActiveBuffer->getHeight();
1080            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1081                bufHeight != uint32_t(oldActiveBuffer->height)) {
1082                recomputeVisibleRegions = true;
1083            }
1084        }
1085
1086        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1087        if (oldOpacity != isOpaque()) {
1088            recomputeVisibleRegions = true;
1089        }
1090
1091        // FIXME: postedRegion should be dirty & bounds
1092        const Layer::State& s(getDrawingState());
1093        Region dirtyRegion(Rect(s.active.w, s.active.h));
1094
1095        // transform the dirty region to window-manager space
1096        outDirtyRegion = (s.transform.transform(dirtyRegion));
1097    }
1098    return outDirtyRegion;
1099}
1100
1101uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1102{
1103    // TODO: should we do something special if mSecure is set?
1104    if (mProtectedByApp) {
1105        // need a hardware-protected path to external video sink
1106        usage |= GraphicBuffer::USAGE_PROTECTED;
1107    }
1108    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1109    return usage;
1110}
1111
1112void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1113    uint32_t orientation = 0;
1114    if (!mFlinger->mDebugDisableTransformHint) {
1115        // The transform hint is used to improve performance, but we can
1116        // only have a single transform hint, it cannot
1117        // apply to all displays.
1118        const Transform& planeTransform(hw->getTransform());
1119        orientation = planeTransform.getOrientation();
1120        if (orientation & Transform::ROT_INVALID) {
1121            orientation = 0;
1122        }
1123    }
1124    mSurfaceFlingerConsumer->setTransformHint(orientation);
1125}
1126
1127// ----------------------------------------------------------------------------
1128// debugging
1129// ----------------------------------------------------------------------------
1130
1131void Layer::dump(String8& result, Colorizer& colorizer) const
1132{
1133    const Layer::State& s(getDrawingState());
1134
1135    colorizer.colorize(result, Colorizer::GREEN);
1136    result.appendFormat(
1137            "+ %s %p (%s)\n",
1138            getTypeId(), this, getName().string());
1139    colorizer.reset(result);
1140
1141    s.activeTransparentRegion.dump(result, "transparentRegion");
1142    visibleRegion.dump(result, "visibleRegion");
1143    sp<Client> client(mClientRef.promote());
1144
1145    result.appendFormat(            "      "
1146            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1147            "isOpaque=%1d, invalidate=%1d, "
1148            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1149            "      client=%p\n",
1150            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1151            s.active.crop.left, s.active.crop.top,
1152            s.active.crop.right, s.active.crop.bottom,
1153            isOpaque(), contentDirty,
1154            s.alpha, s.flags,
1155            s.transform[0][0], s.transform[0][1],
1156            s.transform[1][0], s.transform[1][1],
1157            client.get());
1158
1159    sp<const GraphicBuffer> buf0(mActiveBuffer);
1160    uint32_t w0=0, h0=0, s0=0, f0=0;
1161    if (buf0 != 0) {
1162        w0 = buf0->getWidth();
1163        h0 = buf0->getHeight();
1164        s0 = buf0->getStride();
1165        f0 = buf0->format;
1166    }
1167    result.appendFormat(
1168            "      "
1169            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1170            " queued-frames=%d, mRefreshPending=%d\n",
1171            mFormat, w0, h0, s0,f0,
1172            mQueuedFrames, mRefreshPending);
1173
1174    if (mSurfaceFlingerConsumer != 0) {
1175        mSurfaceFlingerConsumer->dump(result, "            ");
1176    }
1177}
1178
1179void Layer::dumpStats(String8& result) const {
1180    mFrameTracker.dump(result);
1181}
1182
1183void Layer::clearStats() {
1184    mFrameTracker.clear();
1185}
1186
1187void Layer::logFrameStats() {
1188    mFrameTracker.logAndResetStats(mName);
1189}
1190
1191// ---------------------------------------------------------------------------
1192
1193Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1194        const sp<Layer>& layer)
1195    : mFlinger(flinger), mLayer(layer) {
1196}
1197
1198Layer::LayerCleaner::~LayerCleaner() {
1199    // destroy client resources
1200    mFlinger->onLayerDestroyed(mLayer);
1201}
1202
1203// ---------------------------------------------------------------------------
1204}; // namespace android
1205
1206#if defined(__gl_h_)
1207#error "don't include gl/gl.h in this file"
1208#endif
1209
1210#if defined(__gl2_h_)
1211#error "don't include gl2/gl2.h in this file"
1212#endif
1213