Layer.cpp revision f75514079434cefcdb746e8b083708d6de5f86ff
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
3790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
410f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
43b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
48875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
63a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mDebug(false),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
8303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mPotentialCursor(false)
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
934125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
117e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
118e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
120bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
121b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
122b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
123b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
124b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
125b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
127399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1307f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1317f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
132bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1337f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
135303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1366905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14096f0819f81293076e652792794a961543e6750d7Mathias Agopian
1414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14996f0819f81293076e652792794a961543e6750d7Mathias Agopian
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
154c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
162a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1633d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
16499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
165579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
166579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
167399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
168399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
169399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
170399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
171399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
172399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
173399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
178bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
17948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
180cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
21113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
21413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
21513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
224882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
228882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
231882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
234a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
235a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
239a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
242582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
243582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
244b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
245b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
25013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
25113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
252a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
253a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
254a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
255f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
256f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
257a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
258f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
259a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
260a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
261a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
262f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
263a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
265f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
266f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
267f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
268f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
269f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
270f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
271f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
272f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
273f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
274f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
275f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
276f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
277f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
278f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
27913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2856c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
286f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2896b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2926b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3006b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3016b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3026b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3036b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3040e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3050e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3060e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3070e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3080e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3090e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3100e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
318f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
319f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
320f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
32313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3256b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
326f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
327f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
328f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
329f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
330f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
331f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
332f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
333f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
334f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
335f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
336f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
337f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
338f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
339f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
34413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
34513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
349f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3516b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3526b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3536b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
355f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
356f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
357f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
358f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
36413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
36613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
36713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
371a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
373a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3753e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
376a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
377dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
378dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
379dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
380dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
38113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
3834125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
38413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
39513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3969f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3979f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
39829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
39929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
40029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
40129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
40229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
40329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
40429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
40529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
40629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
407c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
408c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
409c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
410c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
411c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
412c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
413c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
414c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
415c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
416c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
417c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
418c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
419c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
420c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        transform = transform * Transform(invTransform);
421c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
42229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
42329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
42413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
4273e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
428a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
430a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
431a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
432a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
434d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
43513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
43613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
43713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
43813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
43913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
44013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
44113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
44213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
44313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
444399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
445399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
446399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
447399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
448399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
449399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
450399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
451c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
452dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
453c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
454d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
455c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
456d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
457d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
458d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
459d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
46003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
461bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4621df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
463c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
464dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
465dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
466dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
467dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
468dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
469c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
470c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
471c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
47203414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
47303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
47403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
47503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
47603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
47703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
47803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
47903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
48003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
48103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
48203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
48303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
48403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
48503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
48603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
48703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
48803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
48903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
49003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
49103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
49213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
49313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
497c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
49813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
49913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
500c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
501c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
502c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
50313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
50413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
505c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
506c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
507c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
508c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
509c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
510c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5121c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
516179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
517179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
518179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
519179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
520179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
521179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
522179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
523179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
524179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
525f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
526f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
527179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
528179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
52913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
531179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
5324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
533179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
534179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
535179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
536179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
5371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
538179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
541a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
54297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
54397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
544bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
545bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
54697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
547dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
548dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
549dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
550dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
551dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
552dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
553875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
554875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
555dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
556cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
557eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
558cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
559cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
560cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
561bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
562bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
563cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
564c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
565c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
566c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
567c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
568c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
569c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
570c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
571c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
572c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
573c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
574c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
575c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
576c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
577c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
578c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
579c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
580c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
581c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
582c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
583c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
584c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
585c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
586c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
587c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
588c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
589c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
590c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
591c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
592cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
59349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
59449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
59549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
59649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
59749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
599875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
601c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
602875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
606c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
607c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
608c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
60913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
61019733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
611c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
61219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
61319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
61813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
61913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
621c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
622c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
62313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
6241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
63013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
63213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
63313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
63413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
63513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
63813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
63913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
64013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
64113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
64213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
6443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
6453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
6463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
6473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
64813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
649875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
650875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
651ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
652ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
653ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
654ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
655ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
657875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
6584125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
6595cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
660875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
66113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
6631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
6641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
6651681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
6661681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
6671681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
6681681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
6691681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
6701681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
6711681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
6721681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
6731681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
67413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
67513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
67613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
67713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
67813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
67913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
68013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
68113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
682ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
683ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
684ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
685ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
686ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
687ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
688ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6895773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
690a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
691a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
692ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
6935773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
6945773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
6955773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
696c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_A_8888:
697dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
6985773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
6995773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
700dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
701ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
702ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
70313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
707c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
708c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
7101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
711c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
712c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
71713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
7186c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
719f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
7203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
721ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
722ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
723ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
724ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
725ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
7263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
7275cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
72813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
730ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
7314125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
732a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
733a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
734a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
735db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
736a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
737db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
738a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
739a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
740a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
7414125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
742a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
743a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
7447a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
7457a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
746a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
7477a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
7487a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
7497a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
750b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
76913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
77113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
77513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
7841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
7871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
7901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
791a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
792a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
7949d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
7956905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
796419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
797419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
798419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
799419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
8001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
8011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
8021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
8031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
8041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
8051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
8061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
8071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
8081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
8091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
8101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
8111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
8121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
8131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
8141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
8151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
8161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
8171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
8181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
8191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
8201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
8211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
8221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
8231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
8241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
8251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
8261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
8271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
8281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
829a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
8302a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
8312a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
832bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
8331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
835cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
8360cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
8370cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
8381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
8391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
8400cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
8410cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
8430cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
8440cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
8450cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
8460cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
8470cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
8480cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
8490cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
8500cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
8510cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
8520cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
8530cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
8540cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
8591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
8601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
8681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
86913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
8741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
8751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
886a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
887a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
88913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
89313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
89413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
90313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
90513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
91813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
91913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
92113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
92313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
92413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
92513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
92613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
92713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
92913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
93013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
93113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
93213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
93313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
93413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
93513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
9362ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
93713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
93813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
93913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
94013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
94113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
94213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
94313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
94413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
94513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
94613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
94713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
94813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
94913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
95013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
95113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
95213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
95313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
95513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
95613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
95713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
95913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
96313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
96413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
965a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
966a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9714d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
9724d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
973399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
97499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
97599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
976d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
977d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
978bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
97982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
98082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
981bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
982789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
98382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
98482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
98582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
98682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
98782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
98882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
98982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
990d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
99182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
992789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
99382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
99482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
99582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
99682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
99782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
99882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
99982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
100082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
100182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1002d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1003d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1004d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1005d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1006da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1009afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1010da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1011da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
10124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10141c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10151c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1016399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1017399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1018399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1019399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1020399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
10223d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
102499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
102599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
102699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
102799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
102899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
10294d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
10304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1033351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
10344125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
10354125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1036351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1037db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1038bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
10392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
10402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
10412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
10421681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
10432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
10441681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
10452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
10461681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
10471681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
10482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
1051db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    const IGraphicBufferConsumer::BufferItem& item) {
10522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
10532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
10542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
10572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
10582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
10602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
10612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
10622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
10632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
10662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
10672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
10692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
10702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
10712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
10722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
10732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
10742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
10752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
10762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
10782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
10792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
10802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
10812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
10822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
10832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
10842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
10862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
10872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
10906905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
10912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
10922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10936905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
10942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
10952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
10962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
10972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
10982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
10992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
11002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
11012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
11022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
11032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
11042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
11052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
11062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
11072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
11082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11101681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
11112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
11122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
11134824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
11141681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
11151681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
11162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
11172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
11182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11192ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
11202ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
11212ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
11222ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
11232ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
11242ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
11252ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
11262ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
11276c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
11286c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
11296c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
11306c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
11316c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
11326c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
11336c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
11346c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
11356c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
11366c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
11372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
11382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
11392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
11402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
11412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
11422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
11432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11441681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
11451681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
11462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
114741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
114841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden                mFlinger->mPrimaryDispSync);
11491585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
11501585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
11511585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
11521585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11531585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
11541585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11551585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11561585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
11571585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
11581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
11591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
11601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
11611585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
11621585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1163a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1164a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
11654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1166a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1167d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1168351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1169bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1170e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1171e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
11724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1173e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1174da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
11754824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1176702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1177e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
11782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
11792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1180ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
11812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1182702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1183bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1184bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1185bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1186702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1187702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1188702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1189702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1190702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1191702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1192702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1193ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1194702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1195702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1196702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1197e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1198e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1199702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1200702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1201ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1202702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1203702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1204702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1205702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
12064125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1207702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1208702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1209702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
12104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
12111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
12121c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
12134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
12141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
122413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
122603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
122703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
122803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
122913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
123013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
123113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
123213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
123313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
123413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
123513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
123613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
123713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
123813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
123913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
124013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
124113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
124213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
124313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
124413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
124513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
124613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
124713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
124813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
124913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
125013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
125113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
12531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
12541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
125513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
125774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
125813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
12603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
126113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12622ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
126313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
126413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
126513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
126713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
126813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
126913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
127013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
127113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
127213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
127313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
12744125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
127513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
127613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
127713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
127813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
12791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1280a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1281a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
12821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
12831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
12841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
12851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1286a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
12871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
128874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
12891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1290ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
12916905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1292a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
12936905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
12941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1295bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
129674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1297bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1298d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1299d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1300d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1301d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
130282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
130382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1304d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1305d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
130625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
130725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
13086547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
13096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
13106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
13116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1312d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1313d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1314d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1315d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
131613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
131713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
131813127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
131913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
132013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1321b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1322b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
132313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
132413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
132513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1326a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1327a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
13293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
13323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
13333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
13363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
13373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1338