Layer.cpp revision b3d0bdf0dbc19f0a0d7d924693025371e24828fd
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
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
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>
2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
3790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
410f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
43b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
48875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
63a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mDebug(false),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mClientRef(client)
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
84a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
116e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
117e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
119bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
120b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
121b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
122b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
123b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
124b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
125bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
126399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
128b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1297f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1307f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1327f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
133bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
134303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1356905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
13996f0819f81293076e652792794a961543e6750d7Mathias Agopian
1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
145921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
153c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15713f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
161a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1623d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
16399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
164579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
165579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
166399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
167399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
168399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
169399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
170399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
171399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
172399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
17613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
177bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
17848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
179cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
21313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
222882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
226882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
229882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
232a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
233a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
237a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
240582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
241582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
242b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
243b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
24813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
250a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
251a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
252a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
254f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
255a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
256f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
257a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
258a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
259a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
260f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
261a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
263f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
264f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
265f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
266f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
267f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
268f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
269f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
270f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
271f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
272f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
273f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
274f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
275f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
276f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
27713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2836c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
284f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2876b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2906b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
2986b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
2996b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3006b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3016b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3020e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3030e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3040e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3050e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3060e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3070e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3080e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
316f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
317f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
318f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
32013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
32713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
32813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
32913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                invTransform, s.active.w, s.active.h);
33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3356b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3366b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3376b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
33813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3396b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetL = winCrop.left                 * xScale;
3406b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetT = winCrop.top                  * yScale;
3416b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
3426b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
34413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
34513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
35113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
355a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
357a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3583e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
360a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
361dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
362dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
363dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
364dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
3674125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
36813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
36913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3809f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3819f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
38229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
38329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
38429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
38529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
38629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
38729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
38829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
38929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
39029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
391c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
392c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
393c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
394c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
395c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
396c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
397c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
398c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
399c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
400c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
401c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
402c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
403c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
404c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        transform = transform * Transform(invTransform);
405c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
40629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
40729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
40913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
41013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
4113e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
412a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
414a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
415a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
416a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
418d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
42013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
42113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
42213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
42313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
42413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
428399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
429399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
430399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
431399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
432399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
433399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
434399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
435c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
436dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
437c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
438d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
439c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
440d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
441d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
442d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
443d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
444d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
445bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4461df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
447c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
448dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
449dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
450dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
451dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
452dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
453c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
454c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
455c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
45713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
45813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
461c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
464c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
465c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
466c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
469c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
470c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
471c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
472c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
473c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
474c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4761c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4771c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
478a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
480179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
481179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
482179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
483179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
484179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
485179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
486179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
487179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
488179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
489f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
490f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
491179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
492179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
49313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
495179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
4964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
497179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
498179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
499179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
500179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
5011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
502179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
505a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
50697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
50797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
508bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
509bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
51097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
511dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
512dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
513dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
514dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
515dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
516dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
517875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
518875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
519dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
520cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
521eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
522cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
523cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
524cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
525bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
526bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
527cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
528c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
531c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
533c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
534c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
535c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
536c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
537c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
538c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
539c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
540c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
541c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
542c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
543c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
544c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
545c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
546c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
547c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
548c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
549c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
550c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
551c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
552c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
553c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
554c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
555c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
556cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
55749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
55849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
55949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
56049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
56149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
563875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
565c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
566875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
570c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
571c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
572c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
57313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
57419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
575c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
57619733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
57719733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
57813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
57913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
58013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
58213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
58313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
58413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
585c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
586c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
58713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
5881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
58913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
590c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
59113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
59213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
59413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
59513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
59613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
59713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
59813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
59913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
60013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
601c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
60613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
60713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
6083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
6093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
6103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
6113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
61213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
613875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
614875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
615ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
616ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
617ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
618ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
619ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
62013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
621875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
6224125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
6235cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
624875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
63213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
63313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
635ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
636ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
637ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
638ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
639ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
640ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
641ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6425773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
643a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
645ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
6465773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
6475773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
6485773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
649c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_A_8888:
650dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
6515773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
6525773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
653dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
654ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
655ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
65813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
660c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
661c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
6631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
664c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
665c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
66613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
66713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
66813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
66913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
67013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
6716c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
672f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
6733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
674ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
675ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
676ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
677ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
678ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
6793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
6805cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
68113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
68213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
683ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6844125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
685a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
686a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
688db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
689a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
690db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
691a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
692a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
693a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
6944125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
695a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
696a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
6977a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
6987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
699a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
7007a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
7017a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
7027a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
703b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
71013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
71713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
71813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
71913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
72013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
72113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
72213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
72313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
72413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
72513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
72613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
72713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
72813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
73113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
73213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
73313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
73413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
73513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
73613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
7371c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7381c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
7401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
7431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
744a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
745a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
746cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
7479d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
7486905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
749419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
750419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
751419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
752419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
7531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
7541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
7551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
7571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
7581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
7591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
7601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
7611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
7621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
7631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
7641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
7651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
7661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
7671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
7681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
7691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
7701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
7711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
7721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
7731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
7741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
7751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
7761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
7771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
7781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
7791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
7801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
7811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
782a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
7832a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
7842a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
785bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
7861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
788cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
7900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
7921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
7930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
7960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
7970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
7980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
7990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
8000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
8010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
8020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
8030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
8040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
8050cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
8060cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
8070cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
81013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
81113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
8121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
8131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
8271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
8281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
839a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
840a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
85913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
86013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
86913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
88613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
88713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
8892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
89413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
90313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
90413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
90513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
918a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
919a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
9254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
926399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
92799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
92899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
929d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
930d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
931bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
93282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
93382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
934bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
935789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
93682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
93782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
93882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
93982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
94082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
94182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
94282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
943d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
94482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
945789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
94682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
94782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
94882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
94982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
95082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
95182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
95282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
95382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
95482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
955d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
956d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
957d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
958d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
959da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            && (mActiveBuffer != NULL);
963da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
964da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
9654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9671c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9681c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
969399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
970399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
971399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
972399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
973399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
9744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
9753d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
97699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
97799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
97899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
97999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
98099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
98199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
9824d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
98499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
98599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
986351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
9874125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
9884125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
989351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
990db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
991bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
9922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
9932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
9942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
9952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
9962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
9972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
9982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
9992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
1002db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    const IGraphicBufferConsumer::BufferItem& item) {
10032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
10042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
10052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
10082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
10092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
10112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
10122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
10132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
10142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
10172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
10182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
10202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
10212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
10222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
10232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
10242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
10252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
10262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
10272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
10292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
10302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
10312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
10322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
10332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
10342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
10352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
10372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
10382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
10416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
10422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
10432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
10452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
10462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
10472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
10482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
10492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
10502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
10512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
10522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
10532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
10542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
10552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
10562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
10572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
10582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
10592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
10622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
10632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
10644824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
10654ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
10664ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //        bufWidth, bufHeight, front.active.w, front.active.h);
10672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
10682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10712ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
10722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
10732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
10742ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
10752ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
10762ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
10772ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
10786c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10796c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
10806c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
10816c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
10826c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
10836c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
10846c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
10856c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
10866c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10876c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
10882ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
10892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
10902ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
10922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
10942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
10972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10981585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
10991585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
11001585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
11011585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
11021585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11031585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
11041585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11051585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
11071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
11081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
11091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11101585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11111585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11121585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1114a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
11154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1116a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1117d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1118351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1119bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1120e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1121e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
11224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1123e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1124da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
11254824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1126702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1127e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
11282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
11292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1130ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
11312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1132702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1133bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1136702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1137702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1138702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1139702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1140702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1141702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1142702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1143ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1144702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1145702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1146702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1147e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1148e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1149702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1150702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1151ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1152702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1153702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1154702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1155702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
11564125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1157702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1158702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1159702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
11604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
11611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
11621c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
11634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
11641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
12001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
12011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
120213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12033e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
120474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
120513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
120613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
12073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
120813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12092ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
121013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
121113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
121213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
121374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
121413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
121813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
12214125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
122413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
12261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1227a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1228a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
12291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
12301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
12311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
12321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1233a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
12341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
123574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
12361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1237ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
12386905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1239a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
12406905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
12411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1242bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
124374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1244bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1245d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1246d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
124774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const {
124882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
124982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
125082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
125113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() {
125282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
125325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
125425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
12556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
12566547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
12576547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
12586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
126013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
126213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
126313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1264b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1265b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
126613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
126713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
126813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1269a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1270a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
12723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
12753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
12763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
12793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
12803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1281