Layer.cpp revision 12e0a27aa30d9db10eafe88904d3eb8fdcbcfa71
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
376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h>
3890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
44b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
50875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
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),
8203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
8303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mPotentialCursor(false)
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
934125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
117e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
118e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
120bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
121b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
122b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
123b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
124b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
125b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
127399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
130ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza    // Set the shadow queue size to 0 to notify the BufferQueue that we are
131ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza    // shadowing it
132ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza    mSurfaceFlingerConsumer->setShadowQueueSize(0);
133ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1347f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1357f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
136bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1377f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
138bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
139303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1406905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian
1454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
150921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
15396f0819f81293076e652792794a961543e6750d7Mathias Agopian
15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
158c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
16213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
16313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1666b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
1706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
171ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
172ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
1736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
17599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
176579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
177579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1786b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
1796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
1806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    if (mQueueItems.empty()) {
1816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        ALOGE("Can't replace a frame on an empty queue");
1826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return;
1836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    mQueueItems.editItemAt(0) = item;
1856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
1866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
187399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
188399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
189399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
190399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
191399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
192399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
193399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1946710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1956710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1966710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
19948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
200cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
21313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
21413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
21613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
21713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
21813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
21913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
22013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
22113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
22313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
22513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
22613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
22713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
22813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
23013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
23113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
23213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
23313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
23413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
244882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
248882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
251882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
254a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
255a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
259a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
262582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
263582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
264b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
265b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
272a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
273a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
274a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
275f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
276f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
277a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
278f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
279a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
280a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
281a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
282f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
283a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
285f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
286f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
287f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
288f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
289f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
290f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
291f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
292f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
293f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
294f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
295f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
296f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
297f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
298f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
29913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3016c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3026c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3036c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3046c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3056c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3106c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3116c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3146b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3176b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
32013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
32313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3256b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3266b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3276b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3286b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3290e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3300e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3310e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3320e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3330e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3340e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3350e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
33613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
33713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
33813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
33928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
34028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
34128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
34228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
34328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
34428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
34513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
347f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
348f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
349f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
35113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3546b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
355f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
356f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
357f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
358f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
359f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
360f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
361f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
362f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
363f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
3641440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
3651440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
3661440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
3671440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
3681440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
3691440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
3701440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
3711440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
372f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
373f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
374f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
375f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
376f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
3807b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
3817b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
3827b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
3837b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
3847b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
3857b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
3867b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
3877b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
3887b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
3897b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
3907b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
395f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3976b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3986b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3996b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
40013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
401f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
402f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
403f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
404f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
40913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
41013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
41113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
41213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
417a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
419a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4203e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4213e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
422a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
423dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
424dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
425dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
426dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4294125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
43313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
43513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
43613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4386c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4396c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4406c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4416c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4426c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
44328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
44428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
44528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
44628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
44728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
44828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
44928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
4506c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
4516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
4526c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
4536c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
4546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
4556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
4566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
4576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
4586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
4596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
46313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
4649f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
4659f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
46629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
46729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
46829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
46929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
47029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
47129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
47229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
47329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
47429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
475c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
476c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
477c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
478c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
479c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
480c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
481c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
4821440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
483c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
484c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
485c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
486c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
4871440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
4881440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
4891440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4901440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4911440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
4921440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4931440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4941440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
495c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
496c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
4971440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
498c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
49929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
50029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
50313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
5043e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
505a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
50613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
507a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
508a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
509a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5104297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
511d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
51813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
51913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
52013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
521ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    // Pass full-surface damage down untouched
522ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (surfaceDamageRegion.isRect() &&
523ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
524ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamageRegion);
525ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
526ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        Region surfaceDamage =
527ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
528ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamage);
529ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
530ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
531399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
532399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
533399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
534399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
535399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
536399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
537399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
538c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
539dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
540c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
541d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
542c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
543d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
544d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
545d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
546d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
54703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
548bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5491df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
550c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
551dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
552dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
553dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
554dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
555dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
556c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
557c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
558c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
55903414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
56003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
56103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
56203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
56303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
56403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
56503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
56603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
56703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
56803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
56903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
57003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
57103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
57203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
57303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
57403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
57503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
57603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
57703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
57803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
57913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
58013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
58213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
58313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
584c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
58513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
58613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
587c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
588c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
589c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
59013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
59113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
592c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
593c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
594c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
595c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
596c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
597c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5991c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
603179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
604179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
605179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
606179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
607179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
608179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
609179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
610179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
611179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
612f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
613f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
614179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
615179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
618179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
620179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
621179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
622179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
623179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6241b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
625179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
62997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
63097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
631bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
632bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
63397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
634dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
635dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
636dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
637dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
638dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
639dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
640875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
641875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
642dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
643cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
644eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
645cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
646cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
647cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
648bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
649bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
650cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
651c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
652c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
653c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
654c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
655c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
656c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
657c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
658c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
659c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
660c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
661c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
662c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
663c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
664c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
665c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
666c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
667c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
668c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
669c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
670c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
671c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
672c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
673c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
674c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
675c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
676c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
677c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
678c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
679cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
68049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
68149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
68249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
68349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
68449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
685a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
686875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
688c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
689875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
693c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
694c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
695c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
69613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
69719733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
698c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
69919733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
70019733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
70113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
708c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
709c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
712c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
71713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
71813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
71913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
72013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
72113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
72213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
723c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
72413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
72513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
72613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
72713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
72813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
73413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
735875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
736875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
737ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
738ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
739ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
740ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
741ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
74213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
743875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7444125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7455cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
746875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7491681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7501681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7511681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7521681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7531681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
7541681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
7551681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
7561681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
7571681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
7581681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
7591681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
768ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
769ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
770ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
771ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
772ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
773ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
774ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
7755773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
776a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
777a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
778ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
7795773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
7805773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
7815773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
782dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
7835773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
7845773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
785dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
786ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
787ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
79113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
792c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
793c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
7951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
796c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
797c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
80213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
8036c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
804f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
806ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
807ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
808ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
809ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
810ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8125cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
815ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8164125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
817a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
818a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
819a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
820db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
821a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
822db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
823a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
824a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
825a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8264125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
827a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
828a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
8297a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
8307a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
831a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
8327a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
8337a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
8347a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
835b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
85913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
86013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
8691c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8701c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
8711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
8721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
8751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
876a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
877a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
878cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
8799d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
8806905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
881419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
882419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
883419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
884419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
8851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
8861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
8871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
8881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
8891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
8901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
8911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
8921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
8931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
8941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
8951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
8961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
8971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
8981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
8991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
9001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
9011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
9021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
9031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
9041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
9051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
9061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
9071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
9101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
9111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
9121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
9131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
914a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
9152a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
9162a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
917bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
9181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
920cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
9210cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
9220cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
9241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
9250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9269e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
92713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
9280cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
9290cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
9300cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
9310cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
9320cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
9330cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
9340cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
9359e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
9369e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
9379e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
9389e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
9390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9400cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
9410cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
9420cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
9430cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
94413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
94513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
94613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
94713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
9481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
9491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
95013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
95113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
95313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
95513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
95613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
95913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
9631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
9641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
96513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
96613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
96713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
96813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
96913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
97013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
97413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
975a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
976a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
10252ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
103613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
103813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
103913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
104013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
104413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
104513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
104913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
105013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
105113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
105213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
105313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1054a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1055a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1056ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1057ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1058ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1059ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1060ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1061ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1062ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1063ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1064ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1065ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1066ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1067ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10726b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
10736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
10746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
10756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
10766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return mQueueItems.empty() ?
10776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            false : mQueueItems[0].mTimestamp < expectedPresent;
10786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
10796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
10804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
10814d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1082399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
108399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
108499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1085d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1086d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1087bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
108882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
108982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1090bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1091789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
109282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
109382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
109482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
109582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
109682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
109782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
109882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1099d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
110082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1101789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
110282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
110382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
110482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
110582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
110682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
110782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
110882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
110982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
111082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1111d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1112d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1113d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1114d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1115da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1118afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1119da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1120da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
11214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
11241c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1125399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1126399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1127399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
112812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
112912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
113012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
113112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
11325bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
11335bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
11345bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
11355bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1136399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1137399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
11393d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
114099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
114199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
114299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
114399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
114499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
114599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
11464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
11474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
114899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
114999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1150351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
11514125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
11524125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1153351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1154db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1155bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
11562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
11572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
11582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
11591681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
11602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
11611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
11622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
11631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
11641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
11652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
11662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
116811611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
11692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
11702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
11712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
11742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
11752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
11772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
11782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
11792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
11802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
11832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
11842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
11862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
11872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
11882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
11892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
11902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
11912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
11922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
11932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
11952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
11962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
11972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
11982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
11992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
12002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
12012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
12032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
12042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
12052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
12076905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
12082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
12092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
12106905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
12112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
12122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
12132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
12142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
12152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
12162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
12172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
12182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
12192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
12202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
12212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
12222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
12232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
12242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
12252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12271681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
12282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
12292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
12304824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
12311681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
12321681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
12332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
12342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
12352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12362ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
12382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
12392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
12402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
12412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
12422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
12432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
12446c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12456c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
12466c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
12476c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
12486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
12496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
12506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
12516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
12526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
12542ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
12552ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
12562ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
12582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
12592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
12602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
12621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
12632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
126441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
126541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden                mFlinger->mPrimaryDispSync);
12661585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
12671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
12681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
12691585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
12701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1271ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1272ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1273ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1274ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            Mutex::Autolock lock(mQueueItemLock);
1275ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1276ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Update the BufferQueue with the new shadow queue size after
1277ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // dropping this item
1278ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            mQueueItems.removeAt(0);
1279ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
1280ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1281ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            android_atomic_dec(&mQueuedFrames);
1282ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
12831585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
12841585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
12856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        { // Autolock scope
1286ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1287ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
12886b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1289ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1290ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1291ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1292ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1293ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1294ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1295ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1296ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1297ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Update the BufferQueue with our new shadow queue size, since we
1298ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // have removed at least one item
12996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
1300ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
13016b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13026b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1303ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
13041585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
13051585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
13061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
13071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
13081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
13091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
13101585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1311a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1312a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
13134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1314a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1315d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1316351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1317bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1318e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1319e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
13204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1321e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1322da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
13234824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1324702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1325e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
13262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
13272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1328ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
13292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1330702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1331bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1332bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1333bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1334702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1335702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1336702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1337702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1338702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1339702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1340702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1341ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1342702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1343702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1344702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1345e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1346e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1347702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1348702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1349ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1350702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1351702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1352702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1353702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
13544125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1355702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1356702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1357702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
13584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
13591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
13601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
13621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
136813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
136913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
137013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
137113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
137213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
137313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
137403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
137503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
137603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
137713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
137813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
137913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
138013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
138113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
138213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
138313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
138413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
138513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
138613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
138713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
138813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
138913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
139013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
139113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
139213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
139313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
139413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
139513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
139613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
139713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
139813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
139913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
14011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
14021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
140313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
140574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
140613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
140713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
14083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
140913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14102ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
141113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1412ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
141313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
141413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
141574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
141613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
141713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
141813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
141913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
142113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
142213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
14234125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
142413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
142513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
142613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
142713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
14281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1429a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1430a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
14311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
14321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
14331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
14341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
14361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
143774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
14381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1439ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
14406905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1441a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
14426905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
14431b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1444bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
144574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1446bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1447d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1448d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1449d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1450d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
145182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
145282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1453d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1454d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
145525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
145625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
14576547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
14586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14596547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
14606547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1461d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1462d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1463d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1464d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
146513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
146613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
146713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1470b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1471b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
147213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
147313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1475a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1476a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
14783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
14813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
14823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
14853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
14863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1487