Layer.cpp revision 65476f3332641066a99e22338bf5cf49ce4af642
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h>
3890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
44b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
50875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
83a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
84a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
85a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
86a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
8765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
8865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mUpdateTexImageFailed(false)
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
90a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
9249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
964125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
974125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
984125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
122e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
123e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
125bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
126b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
127b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
128b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
129b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
130b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
132399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1357f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1367f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
137bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1387f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
139bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
140303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian
1464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
151921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1526547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
15496f0819f81293076e652792794a961543e6750d7Mathias Agopian
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
159c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
16213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
16313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1676b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
171a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
172a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
173a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
174a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
175a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
176a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
177a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
178a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
179a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
180a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
181a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
182a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
183a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
184a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
185a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
186a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
188ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
189a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
190a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
191a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
192a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
1936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1946b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
196579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
197579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1986b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
1996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
200a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
201a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    // Ensure that callbacks are handled in order
202a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
203a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
204a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ms2ns(500));
205a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (result != NO_ERROR) {
206a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            ALOGE("[%s] Timed out waiting on callback", mName.string());
207a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
208a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    }
209a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    if (mQueueItems.empty()) {
2116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        ALOGE("Can't replace a frame on an empty queue");
2126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return;
2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    mQueueItems.editItemAt(0) = item;
215a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    // Wake up any pending callbacks
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    mLastFrameNumberReceived = item.mFrameNumber;
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza    mQueueItemCondition.broadcast();
2196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
221399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
222399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
223399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
224399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
225399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
226399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
227399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2296710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2306710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
23113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
232bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
23348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
234cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
23713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
24013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
24113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
24213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
24313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
24413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
24713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
24813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
25013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
25113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
25213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
25313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
25413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
25513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
25613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
25713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
25803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
26113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
26213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
278882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
282882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
285882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
288a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
289a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
293a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
296582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
297582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
298b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
299b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
306a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
307a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
308a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
309f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
310f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
311a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
312f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
313a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
314a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
315a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
316f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
317a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
319f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
320f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
321f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
322f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
323f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
324f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
325f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
326f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
327f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
328f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
329f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
330f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
331f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
332f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
33313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3356c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3386c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3396c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3446c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3456c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3486b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3516b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3596b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3606b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3616b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3626b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3630e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3640e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3650e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3660e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3670e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3680e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3690e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
37428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
37528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
37628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
37728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
37828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
38013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
381f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
382f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
383f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
38413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
389f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
390f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
391f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
392f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
393f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
394f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
395f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
396f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
397f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
3981440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
3991440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
4001440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4011440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4021440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
4031440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4041440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
4051440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
406f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
407f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
408f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
409f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
410f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
41113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
41213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
4147b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
4157b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
4167b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
4177b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
4187b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
4197b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4207b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4217b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
4227b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4237b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4247b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
429f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4316b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
4326b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
4336b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
435f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
436f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
437f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
438f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
43913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
44013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
44113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
44213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
44313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
44413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
44513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
451a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
45213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
453a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4543e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4553e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
456a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
457dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
458dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
459dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
460dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4634125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
46413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
46813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
46913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
47013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4716c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
47728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
47828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
47928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
48028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
48128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
48228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
48328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
4846c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
4856c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
4866c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
4876c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
4886c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
4896c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
4906c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
4916c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
4926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
4936c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
4989f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
4999f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
50029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
50129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
50229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
50329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
50429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
50529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
50629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
50729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
50829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
509c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
510c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
511c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
512c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
513c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
514c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
515c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
5161440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
517c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
518c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
519c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
520c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
5211440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
5221440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
5231440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
5241440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
5251440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
5261440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
5271440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
5281440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
5311440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
53329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
53429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
53513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
53613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
53713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
5383e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
539a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
54013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
541a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
542a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
543a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
545d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
54713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
54813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
54913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
55013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
55113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
55213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
55313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
55413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
555ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    // Pass full-surface damage down untouched
556ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (surfaceDamageRegion.isRect() &&
557ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
558ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamageRegion);
559ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
560ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        Region surfaceDamage =
561ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
562ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamage);
563ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
564ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
565399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
566399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
567399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
568399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
569399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
570399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
571399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
572c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
573dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
574c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
575d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
576c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
577d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
578d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
579d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
580d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
58103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
582bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
584c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
585dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
586dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
587dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
588dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
589dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
590c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
591c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
592c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
59303414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
59403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
59503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
59603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
59703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
59803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
59903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
60003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
60103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
60203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
60303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
60403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
60503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
60603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
60703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
60803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
60903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
61003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
61103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
61203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
61313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
618c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
61913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
621c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
622c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
623c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
62413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
627c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
628c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
629c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
630c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
631c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
637179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
638179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
639179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
640179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
641179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
642179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
643179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
644179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
645179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
646f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
647f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
648179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
649179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
652179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
654179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
655179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
656179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
657179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
659179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
66397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
66497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
665bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
666bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
66797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
668dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
669dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
670dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
671dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
672dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
673dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
674875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
675875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
676dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
677cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
678eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
679cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
680cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
681cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
682bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
683bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
684cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
685c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
686c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
687c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
688c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
689c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
690c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
691c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
692c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
693c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
694c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
695c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
696c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
697c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
698c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
699c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
700c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
701c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
702c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
703c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
704c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
705c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
706c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
707c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
708c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
709c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
711c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
712c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
713cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
71449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
71549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
71649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
71749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
71849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
719a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
720875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
721a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
722c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
723875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
727c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
728c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
729c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
73119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
732c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
73319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
73419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
73513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
73613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
73913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
74013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
74113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
742c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
743c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
746c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
757c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
769875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
770875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
771ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
772ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
773ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
774ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
775ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
777875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7784125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7795cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
780875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7831681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7841681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7851681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7861681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7871681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
7881681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
7891681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
7901681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
7911681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
7921681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
7931681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
802ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
803ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
804ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
805ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
806ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
807ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
808ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8095773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
810a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
811a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
812ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
8135773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
8145773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
8155773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
816dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
8175773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
8185773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
819dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
820ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
821ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
826c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
827c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
8291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
830c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
831c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
8376c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
838f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
840ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
841ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
842ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
843ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
844ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8465cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
849ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8504125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
851a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
852a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
853a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
854db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
855a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
856db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
857a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
858a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
859a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8604125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
861a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
862a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
8637a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
8647a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
865a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
8667a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
8677a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
8687a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
869b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
88713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
88913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
89313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
89413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
9031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9041c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
9051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
9061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
910a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
911a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
912cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
9139d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
9146905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
915419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
916419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
917419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
918419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
9191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
9201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
9211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
9221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
9231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
9241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
9251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
9261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
9271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
9281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
9291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
9301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
9311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
9321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
9331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
9341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
9351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
9361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
9371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
9381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
9391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
9401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
9411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
9421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
9431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
9441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
9451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
9461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
9471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
948a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
9492a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
9502a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
951bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
9521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
954cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
9550cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
9560cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
9581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
9590cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9609e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
9620cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
9630cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
9640cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
9650cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
9660cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
9670cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
9680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
9699e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
9709e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
9719e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
9729e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
9730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
9750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
9760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
9770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
9821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
9831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
9971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
9981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1009a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1010a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
102513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
103613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
103813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
103913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
104013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
104413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
104513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
104613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
104913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
105013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
105113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
105213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
105313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
105413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
105513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
105613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
105713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
105813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
10592ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
106013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
106113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
106213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
106313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
106413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
106513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
106613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
106713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
106813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
106913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
107013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
107113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
107213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
107313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
107413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
107513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
107613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
107713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
107813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
107913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
108013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
108113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
108213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
108313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
108413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
108513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
108613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
108713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1088a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1089a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1090ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1091ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1092ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1093ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1094ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1095ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1096ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1097ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1098ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1099ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1100ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1101ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11066b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
11076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
11106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return mQueueItems.empty() ?
11116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            false : mQueueItems[0].mTimestamp < expectedPresent;
11126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
11136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
11144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
11154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1116399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
111799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
111899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1119d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1120d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1121bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
112282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
112382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1124bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1125789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
112682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
112782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
112882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
112982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
113082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
113182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
113282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1133d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
113482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1135789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
113682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
113782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
113882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
113982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
114082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
114182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
114282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
114382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
114482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1145d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1146d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1147d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1148d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1149da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1152afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1153da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1154da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
11554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
11581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1159399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1160399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1161399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
116212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
116312e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
116412e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
116512e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
11665bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
11675bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
11685bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
11695bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1170399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1171399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
11724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
11733d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
117499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
117599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
117699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
117799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
117899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
117999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
11804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
11814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
118299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
118399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1184351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
11854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
11864125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1187351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1188db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1189bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
11902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
11912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
11922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
11931681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
11942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
11951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
11962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
11971681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
11981681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
11992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
12002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
120211611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
12032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
12042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
12052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
12082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
12092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
12112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
12122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
12132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
12142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
12172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
12182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
12202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
12212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
12222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
12232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
12242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
12252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
12262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
12272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
12292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
12302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
12312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
12322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
12332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
12342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
12352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
12372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
12382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
12392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
12416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
12422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
12432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
12446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
12452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
12462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
12472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
12482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
12492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
12502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
12512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
12522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
12532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
12542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
12552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
12562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
12572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
12582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
12592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
12622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
12632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
12644824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
12651681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
12661681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
12672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
12682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
12692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12712ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
12722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
12732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
12742ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
12752ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
12762ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
12772ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
12786c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12796c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
12806c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
12816c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
12826c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
12836c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
12846c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
12856c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
12866c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12876c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
12882ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
12892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
12902ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
12922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
12932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
12942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
12961681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
12972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1298a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        uint64_t maxFrameNumber = 0;
1299a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        {
1300a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            Mutex::Autolock lock(mQueueItemLock);
1301a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            maxFrameNumber = mLastFrameNumberReceived;
1302a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1303a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
130441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1305a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                mFlinger->mPrimaryDispSync, maxFrameNumber);
13061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
13071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
13081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
13091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
13101585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1311ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1312ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1313ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1314ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            Mutex::Autolock lock(mQueueItemLock);
1315ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            mQueueItems.removeAt(0);
1316ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            android_atomic_dec(&mQueuedFrames);
1317ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
131865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
131965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
132065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
132165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
132265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
132365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            {
132465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
132565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
132665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
132765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
132865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
132965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
133065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
133165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
133265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
133365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
133465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
133565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
13361585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
13371585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
13386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        { // Autolock scope
1339ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1340ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
13416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1342ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1343ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1344ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1345ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1346ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1347ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1348ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1349ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
13506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
13516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1353ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
13541585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
13551585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
13561585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
13571585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
13581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
13591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
13601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1361a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1362a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
13634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1364a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1365d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1366351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1367bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1368e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1369e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
13704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1371e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1372da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
13734824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1374702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1375e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
13762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
13772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1378ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
13792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1380702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1381bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1382bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1383bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1384702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1385702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1386702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1387702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1388702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1389702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1390702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1391ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1392702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1393702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1394702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1395e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1396e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1397702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1398702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1399ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1400702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1401702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1402702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1403702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
14044125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1405702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1406702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1407702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
14084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
14091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
14101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
14114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
14121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
141813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
141913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
142113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
142213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
142313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
142403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
142503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
142603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
142713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
142813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
142913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
143013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
143113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
143213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
143313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
143413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
143513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
143613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
143713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
143813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
143913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
144113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
144213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
144313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
144413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
144513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
144613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
144713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
144813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
144913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
14511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
14521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
145313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
145574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
145613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
145713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
14583e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
145913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14602ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
146113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1462ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
146313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
146413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
146574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
146613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
146713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
147013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
147113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
147213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
14734125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
147513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
147613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
147713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
14781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1479a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1480a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
14811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
14821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
14831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
14841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1485a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
14861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
148774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
14881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1489ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
14906905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
14926905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
14931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1494bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
149574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1496bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1497d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1498d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1499d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1500d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
150182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
150282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1503d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1504d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
150525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
150625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
15076547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
15086547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
15106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1511d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1512d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1513d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1514d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
151713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1520b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1521b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
152213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
152313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
152413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1525a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1526a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
15283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
15313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
15323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
15353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
15363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1537