Layer.cpp revision 399184a4cd728ea1421fb0bc1722274a29e38f4a
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
3790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
410f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
44a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
48875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
63a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mDebug(false),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mClientRef(client)
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
84a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
116e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
117e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
119bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
120db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mBufferQueue = new SurfaceTextureLayer(mFlinger);
1213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
122bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
123399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
125b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1267f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1277f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
128bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1297f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
130bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
131303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1326905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
135b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
13696f0819f81293076e652792794a961543e6750d7Mathias Agopian
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
13813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
13913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
14113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
142921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
150c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
158a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1593d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
16099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
161579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
162579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
163399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
164399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
165399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
166399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
167399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
168399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
169399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1716710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
17313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
174bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
17548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
176cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
17813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
17913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
219882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
223882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
226882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
229a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
230a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
234a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
237582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
238582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
239db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopiansp<IGraphicBufferProducer> Layer::getBufferQueue() const {
240db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    return mBufferQueue;
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
24513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
247a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
248a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
249a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
252a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
254a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
255a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
256a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
257f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
258a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
260f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
261f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
262f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
263f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
264f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
265f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
266f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
267f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
268f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
269f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
270f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
271f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
272f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
273f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
27413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2806c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
281f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2846b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2876b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
2956b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
2966b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
2976b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
2986b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
2990e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3000e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3010e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3020e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3030e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3040e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3050e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
313f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
314f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
315f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3206b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
32313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
32713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
32813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
32913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                invTransform, s.active.w, s.active.h);
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3326b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3336b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3346b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
33513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3366b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetL = winCrop.left                 * xScale;
3376b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetT = winCrop.top                  * yScale;
3386b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
3396b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
34413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
34513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
352a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
354a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3553e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3563e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
357a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
358dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
359dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
360dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
361dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
3644125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
36613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
36713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
36813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
36913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3779f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3789f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
37929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
38029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
38129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
38229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
38329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
38429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
38529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
38629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
38729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
388c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
389c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
390c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
391c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
392c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
393c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
394c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
395c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
396c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
397c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
398c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
399c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
400c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
401c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        transform = transform * Transform(invTransform);
402c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
40329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
40429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
4083e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
409a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
41013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
411a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
412a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
413a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
415d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
41613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
41713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
42013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
42113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
42213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
42313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
42413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
425399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
426399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
427399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
428399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
429399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
430399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
431399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
432c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
433dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
434c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
435d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
436c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
437d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
438d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
439d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
440d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
441d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
442bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4431df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
444c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
445dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
446dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
447dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
448dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
449dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
450c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
451c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
452c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
45313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
45413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
45513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
45713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
458c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
461c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
462c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
463c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
46413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
466c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
467c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
468c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
469c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
470c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
471c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4731c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4741c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
475a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
477179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
478179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
479179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
480179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
481179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
482179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
483179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
484179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
485179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
486f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
487f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
488179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
489179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
49013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
49113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
492179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
4934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
494179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
495179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
496179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
497179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
4981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
499179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
502a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
50397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
50497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
505bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
506bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
50797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
508dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
509dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
510dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
511dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
512dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
513dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
514875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
515875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
516dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
517cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
518eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
519cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
520cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
521cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
522bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
523bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
524cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
525c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
526c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
527c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
528c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
531c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
533c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
534c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
535c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
536c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
537c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
538c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
539c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
540c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
541c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
542c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
543c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
544c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
545c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
546c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
547c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
548c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
549c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
550c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
551c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
552c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
553cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
55449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
55549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
55649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
55749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
55849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
560875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
562c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
563875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
567c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
568c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
569c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
57119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
572c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
57319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
57419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
57513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
57613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
57713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
57813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
57913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
58013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
582c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
583c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
58413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
5851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
58613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
587c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
58813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
58913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
59013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
59113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
59213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
59413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
59513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
59613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
59713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
598c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
59913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
60013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
60113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
6053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
6063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
6073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
6083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
60913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
610875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
611875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
612ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
613ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
614ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
615ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
616ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
618875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
6194125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
6205cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
621875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
62213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
62613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
63013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
632ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
633ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
634ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
635ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
636ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
637ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
638ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6395773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
642ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
6435773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
6445773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
6455773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
646c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_A_8888:
647dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
6485773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
6495773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
650dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
651ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
652ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
65313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
65513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
657c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
658c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
65913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
6601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
661c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
662c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
66313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
66413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
66513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
66613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
66713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
6686c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
669f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
6703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
671ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
672ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
673ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
674ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
675ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
6763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
6775cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
67813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
67913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
680ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6814125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
682a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
683a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
684a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
685db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
686a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
687db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
688a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
689a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
690a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
6914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
692a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
693a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
6947a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
6957a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
696a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
6977a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
6987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
6997a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
700b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
70113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
70213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
70313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
70713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
71013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
71213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
71713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
71913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
72013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
72113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
72213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
72313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
72413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
72513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
72613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
72713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
72813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
73113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
73213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
73313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
7341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
7371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
7401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
741a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
742a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
743cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
7449d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
7456905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
746419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
747419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
748419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
749419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
7501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
7511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
7521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
7531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
7541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
7551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
7571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
7581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
7591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
7601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
7611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
7621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
7631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
7641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
7651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
7661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
7671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
7681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
7691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
7701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
7711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
7721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
7731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
7741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
7751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
7761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
7771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
7781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
779a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
7802a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
7812a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
782bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
7831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
785cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
7870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
7891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
7900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
7930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
7940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
7950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
7960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
7970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
7980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
7990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
8000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
8010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
8020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
8030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
8040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
80513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
80613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
80713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
8091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
8101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
81113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
81213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
82113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
8241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
8251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
836a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
837a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
85913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
86013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
86913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
8862ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
88713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
88913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
89313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
89413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
90313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
90413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
90513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
915a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
916a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9214d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
9224d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
923399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
92499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
92599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
926d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
927d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
928bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
92982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
93082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
931bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
932789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
93382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
93482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
93582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
93682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
93782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
93882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
93982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
940d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
94182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
942789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
94382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
94482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
94582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
94682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
94782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
94882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
94982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
95082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
95182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
952d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
953d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
954d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
955d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
956da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
95713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
95913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            && (mActiveBuffer != NULL);
960da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
961da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
9624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9641c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9651c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
966399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
967399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
968399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
969399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
970399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
9714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
9723d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
97399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
97499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
97599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
97699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
97799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
97899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
9794d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
9804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
98199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
98299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
983351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
9844125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
9854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
986351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
987db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
988bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
9892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
9902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
9912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
9922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
9932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
9942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
9952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
9962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
9972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
999db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    const IGraphicBufferConsumer::BufferItem& item) {
10002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
10012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
10022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
10052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
10062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
10082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
10092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
10102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
10112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
10142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
10152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
10172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
10182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
10192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
10202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
10212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
10222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
10232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
10242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
10262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
10272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
10282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
10292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
10302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
10312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
10322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
10342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
10352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
10386905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
10392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
10402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
10422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
10432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
10442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
10452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
10462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
10472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
10482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
10492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
10502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
10512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
10522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
10532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
10542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
10552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
10562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
10592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
10602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
10614824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
10624ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
10634ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //        bufWidth, bufHeight, front.active.w, front.active.h);
10642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
10652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10672ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10682ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
10692ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
10702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
10712ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
10722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
10732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
10742ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
10756c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10766c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
10776c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
10786c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
10796c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
10806c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
10816c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
10826c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
10836c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10846c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
10852ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
10862ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
10872ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
10892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
10912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
10942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10951585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
10961585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
10971585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
10981585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
10991585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11001585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
11011585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11021585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11031585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
11041585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
11051585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
11061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1110a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1111a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
11124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1114d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1115351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1116bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1117e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1118e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
11194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1120e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1121da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
11224824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1123702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1124e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
11252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
11262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1127ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
11282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1129702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1130bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1132bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1133702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1134702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1135702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1136702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1137702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1138702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1139702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1140ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1141702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1142702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1143702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1144e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1145e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1146702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1147702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1148ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1149702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1150702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1151702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1152702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
11534125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1154702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1155702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1156702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
11574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
11581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
11591c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
11604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
11611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11963e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
11971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
11981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
120174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
120213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
120313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
12043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
120513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12062ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
120713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
120813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
120913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
121074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
121113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
121213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
121313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
121413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
12184125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
12231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1224a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
12261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
12271b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
12281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
12291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1230a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
12311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
123274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
12331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1234ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
12356905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1236a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
12376905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
12381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1239bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
124074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1241bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1242d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1243d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
124474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const {
124582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
124682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
124782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
124813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() {
124982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
125025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
125125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
12526547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
12536547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
12546547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
12556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
125613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
125713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125813127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
126013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1261b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1262b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
126313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
126413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
126513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1266a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1267a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
12693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
12723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
12733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
12763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
12773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1278