Layer.cpp revision 3bddd5b7731fafd2c60e75416ccd091972d196ae
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),
697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStateMutex(),
707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStates(),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
72399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
74933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
75a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
805cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
84a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
85a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
86a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
87a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
8865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
8904839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
9004839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mSingleBufferMode(false)
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
9449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
984125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
994125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1004125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
101231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
102231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
126e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
127e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
129bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
130b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
131b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
132b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
133b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
134b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
136399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
138b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1397f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1407f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1417f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
14219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
143303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian
1494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
154921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian
15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
162c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
16313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
16613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
16713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::markSyncPointsAvailable(const BufferItem& item) {
1717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto pointIter = mLocalSyncPoints.begin();
1727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (pointIter != mLocalSyncPoints.end()) {
1737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if ((*pointIter)->getFrameNumber() == item.mFrameNumber) {
1747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            auto syncPoint = *pointIter;
1757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            pointIter = mLocalSyncPoints.erase(pointIter);
1767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
1777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mAvailableFrames.push_back(std::move(syncPoint));
1787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
1797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ++pointIter;
1807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
1817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
1837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1846b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
188a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
189a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
190a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
191a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
192a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
193a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
194a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
195a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
196a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
197a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
198a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
199a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
200a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
201a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
202a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
203a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
205ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
206a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
207a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
208a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
209a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
2127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    markSyncPointsAvailable(item);
2137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
21499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
215579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
216579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2176b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItems.editItemAt(0) = item;
2357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
240a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    markSyncPointsAvailable(item);
2426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2436b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
244399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
245399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
246399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
247399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
248399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
249399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
250399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
25413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
255bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
25648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
257cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
25813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
26113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
2937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
2947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
2957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
2967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
2977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
2997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
3007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
317582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
318582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
319b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
320b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
327a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
328a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
329a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
330f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
331f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
332a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
333f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
334a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
335a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
336a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
337f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
338a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
340f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
341f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
342f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
343f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
344f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
345f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
346f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
347f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
348f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
349f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
350f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
351f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
352f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
353f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
35413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3596c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3606c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
36413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3656c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3666c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
36713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
36813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3696b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3726b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3806b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3816b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3826b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3836b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3840e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3850e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3860e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3870e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3880e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3890e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3900e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
39428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
39528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
39628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
39728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
39828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
39928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
40013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
40113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
402f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
403f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
404f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
4096b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
410f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
411f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
412f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
413f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
414f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
415f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
416f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
417f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
418f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4191440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
4201440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
4211440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4221440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4231440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
4241440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4251440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
4261440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
427f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
428f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
429f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
430f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
431f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
43313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
4357b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
4367b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
4377b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
4387b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
4397b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
4407b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4417b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4427b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
4437b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4447b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4457b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
44813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
44913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
450f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
45113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4526b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
4536b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
4546b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
45513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
456f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
457f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
458f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
459f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
46313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
46413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
472a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
47313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
474a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4753e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4763e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
477a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
479dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
480dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
481dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
48213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4844125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
48513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
48613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
48713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
48813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
48913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
49113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4936c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4946c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4956c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4966c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4976c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
49828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
49928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
50028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
50128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
50228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
50328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
50428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
5056c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5066c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5076c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5086c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5096c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5106c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5116c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5126c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5136c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5146c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
51813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
5199f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
5209f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
52129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
52229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
52329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
52429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
52529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
52629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
52729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
52829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
52929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
531c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
533c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
534c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
535c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
536c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
5371440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
538c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
539c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
540c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
541c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
5421440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
5431440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
5441440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
5451440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
5461440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
5471440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
5481440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
5491440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
550c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
551c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
5521440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
553c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
55429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
55529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
55813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
5593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
560a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
56113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
562a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
563a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
564a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
566d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
56713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
57113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
57213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
57313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
57413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
575db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
576ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
577399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
578399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
579399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
580399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
581399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
582399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
583399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
584c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
585dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
586c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
587d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
588c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
589d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
590d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
591d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
592d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
59303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
594bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5951df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
596c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
597dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
598dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
599dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
600dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
601dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
602c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
603c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
604c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
60503414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
60603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
60703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
60803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
60903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
61003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
61103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
61203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
61303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
61403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
61503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
61603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
61703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
61803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
61903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
62003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
62103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
62203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
62303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
62403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
62613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
630c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
633c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
634c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
635c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
638c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
639c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
640c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
641c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
642c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
643c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6461c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
647a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
649179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
650179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
651179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
652179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
653179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
654179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
655179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
656179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
657179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
658f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
659f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
660179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
661179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
66313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
664179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
666179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
667179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
668179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
669179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6701b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
671179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
67697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
677bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
678bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
67997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
680dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
681dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
682dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
683dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
684dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
685dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
686875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
687875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
688dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
689cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
690eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
691cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
692cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
693cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
694bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
695bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
696cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
697c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
698c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
699c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
700c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
701c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
702c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
703c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
704c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
705c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
706c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
707c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
708c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
709c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
711c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
712c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
713c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
714c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
715c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
716c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
717c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
718c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
719c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
720c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
721c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
722c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
723c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
724c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
725cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
72649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
72749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
72849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
72949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
73049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
731a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
732875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
733a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
734c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
735875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
739c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
740c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
741c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
74213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
74319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
744c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
74519733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
74619733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
754c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
755c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
758c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
769c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
77113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
77513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
781875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
782875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
783ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
784ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
785ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
786ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
787ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
789875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7915cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
792875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7961681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7971681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7981681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7991681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
8001681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
8011681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
8021681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
8031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
8041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
8051681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
8067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) {
8077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    uint64_t headFrameNumber = 0;
8087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    {
8097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
8107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!mQueueItems.empty()) {
8117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            headFrameNumber = mQueueItems[0].mFrameNumber;
8127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
8137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            headFrameNumber = mLastFrameNumberReceived;
8147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
8157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
8167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
8177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (point->getFrameNumber() <= headFrameNumber) {
8187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        point->setFrameAvailable();
8197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    } else {
8207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLocalSyncPoints.push_back(std::move(point));
8217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
8227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
8237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
832ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
833ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
834ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
835ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
836ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
837ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
838ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8395773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
840a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
841a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
842ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
8435773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
8445773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
8455773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
846dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
8475773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
8485773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
849dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
850ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
851ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
856c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
857c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
8591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
860c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
861c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
8676c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
868f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
870ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
871ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
872ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
873ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
874ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8765cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
879ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8804125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
881a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
882a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
883a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
884db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
885a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
886db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
887a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
888a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
889a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
891a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
892a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
893231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
894231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
895231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
896231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
897231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
898231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
8997a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
9007a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
901a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
9027a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
9037a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
9047a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
905b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
91913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
92013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
92113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
92313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
92413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
92513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
92613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
92813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
92913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
93013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
93113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
93213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
93313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
93413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
93513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
93613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
93713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
9397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
9407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
9417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mPendingStateMutex);
9447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
9467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
9477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
9487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
9497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
9507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
9517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
9527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
9537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
9547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
9557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
9563bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
9573bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
9583bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
9593bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            handleLayer->addSyncPoint(syncPoint);
9603bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            mRemoteSyncPoints.push_back(std::move(syncPoint));
9617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
9627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
9647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
9657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
9677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::popPendingState() {
9707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto oldFlags = mCurrentState.flags;
9717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState = mPendingStates[0];
9727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
9737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            (mCurrentState.flags & mCurrentState.mask);
9747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
9767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozabool Layer::applyPendingStates() {
9797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mPendingStateMutex);
9807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
9827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
9837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
9847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
9857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
9867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
9877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
9887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
9897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
9927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
9937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
9957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
9967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
10007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
10017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
10027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
10037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            break;
10047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
10057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            popPendingState();
10067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
10077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
10087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
10117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
10127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
10137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
10147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
10157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
10187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
10197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
10227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mAvailableFrameMutex);
10237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    for (auto frame : mAvailableFrames) {
10247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        frame->setFrameAvailable();
10257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
10291c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10301c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
10317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
10327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!applyPendingStates()) {
10337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
10347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
10371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
10401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1041a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1042a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1043cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
10449d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
10456905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1046419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1047419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1048419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1049419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
10511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
10521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
10531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
10541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
10551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
10561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
10571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
10581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
10591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
10601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
10611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
10621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
10631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
10641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
10651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
10661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
10671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
10681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
10691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
10701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
10711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
10721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
10731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
10741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
10751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
10761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
10771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
10781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
1079a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
10802a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
10812a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1082bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
10831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1085cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
10860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
10870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
10891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
10900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10919e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
10930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
10940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
10950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
10960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
10970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
10980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
10990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
11009e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
11019e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
11029e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
11039e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
11040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
11050cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
11060cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
11070cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
11080cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
110913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
111013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
111113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
111213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
11131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
11141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
111813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
111913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
112013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
112313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
112613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
112713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
11281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
11291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
113213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
113413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1140a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1141a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
114613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
114713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
114813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
115213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
115313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
11557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
115613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
115713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
115913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
116013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
116113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
116213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
116313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
11647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
11737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
11827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
11907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
11952ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
11967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
120013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
120113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
120213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
120313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
120413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
120513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
12067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
12077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
120813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
120913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
121013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
121113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
121213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
121313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
121413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
12167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
121813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
122413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
12267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
122713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
122813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1229a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1230a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
12317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
12327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
12337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
12347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
12357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
12367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
12377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
12387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
12397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
12407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1242ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1243ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1244ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1245ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1246ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1247ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1248ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1249ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1250ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1251ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1252ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1253ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12586b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1259063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mSidebandStreamChanged || mSingleBufferMode) {
1260d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1261d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1262d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
12636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
12640eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
12650eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
12660eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
12670eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
12686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
12696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
12700eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12710eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
12720eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
12730eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
12740eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
12750eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
12760eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12770eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
12780eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
12796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
12806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
12814d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
12824d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1283063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
128499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
128599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1286d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1287d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1288bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
128982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
129082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1291bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1292789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
129382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
129482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
129582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
129682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
129782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
129882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
129982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1300d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
130182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1302789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
130382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
130482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
130582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
130682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
130782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
130882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
130982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
131082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
131182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1312d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1313d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1314d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1315d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1316da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
131713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
131813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1319afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1320da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1321da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
13224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13241c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13251c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1326399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1327399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1328399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
132912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
133012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
133112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
133212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
13335bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
13345bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
13355bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
13365bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1337399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1338399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
13394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1340063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mQueuedFrames > 0 || mSingleBufferMode) {
134199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
134299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
134399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
134499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
134599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
134699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
13474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
13484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
134999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
135099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1351351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
13524125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
13534125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1354351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1355db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1356bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
13572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
13582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
13592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
13601681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
13612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
13621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
13632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
13641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
13651681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
13662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
13672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
136911611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
13702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
13712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
13722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
13752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
13762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
13782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
13792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
13802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
13812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
13842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
13852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
13872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
13882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
13892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
13902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
13912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
13922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
13932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
13942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
13962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
13972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
13982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
13992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
14002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
14012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
14022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
14042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
14052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
14086905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
14092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
14102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
14116905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
14122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
14132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
14142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
14152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
14162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
14172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
14182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
14192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
14202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
14212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
14222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
14232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
14242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
14252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
14262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14281681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
14292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
14302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
14314824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
14321681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
14331681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
14342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
14352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
14392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
14402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
14412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
14422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
14432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
14442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
14456c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14466c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
14476c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
14486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
14496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
14506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
14516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
14526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
14536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14546c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
14552ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
14562ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
14572ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
14592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
14602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
14612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
14631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
14642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1465a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        uint64_t maxFrameNumber = 0;
14667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t headFrameNumber = 0;
1467a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        {
1468a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            Mutex::Autolock lock(mQueueItemLock);
1469a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            maxFrameNumber = mLastFrameNumberReceived;
14707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (!mQueueItems.empty()) {
14717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                headFrameNumber = mQueueItems[0].mFrameNumber;
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        bool availableFramesEmpty = true;
14767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
14777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
14787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            availableFramesEmpty = mAvailableFrames.empty();
14797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!availableFramesEmpty) {
14817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
14827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            bool matchingFramesFound = false;
14837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            bool allTransactionsApplied = true;
14847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            for (auto& frame : mAvailableFrames) {
14857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                if (headFrameNumber != frame->getFrameNumber()) {
14867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
14877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
14887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
14897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                allTransactionsApplied &= frame->transactionIsApplied();
14907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (matchingFramesFound && !allTransactionsApplied) {
14927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mFlinger->signalLayerUpdate();
14937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                return outDirtyRegion;
14947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1495a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1496a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1497063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1498063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
1499063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in single
1500063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1501063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
150241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1503063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
1504063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                maxFrameNumber);
15051585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
15061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
15071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
15081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1510ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1511ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1512ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1513063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1514063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1515063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1516063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1517063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1518ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
151965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
152065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
152165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
152265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
152365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1524063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
152565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
152665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
152765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
152865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
152965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
153065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
153165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
153265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
153365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
153465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
153565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
153665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
15371585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15381585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1539063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1540063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1541ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1542ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15436b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1544ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1545ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1546ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1547ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1548ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1549ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1550ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1551ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
15536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
15546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1555ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15561585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
15571585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1558063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1559063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                || mSingleBufferMode) {
15601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15611585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15621585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
15637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!availableFramesEmpty) {
15647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber();
15667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            while (!mAvailableFrames.empty() &&
15677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    frameNumber == mAvailableFrames.front()->getFrameNumber()) {
15687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mAvailableFrames.pop_front();
15697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
15707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
15717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
15721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
15754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1577d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1578351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1579bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1580e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1581e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
15824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1583e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1584da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
15854824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1586702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1587e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
15882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
15892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1590ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
15912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1592702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1593bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1594bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1595bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1596702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1597702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1598702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1599702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1600702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1601702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1602702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1603ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1604702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1605702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1606702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1607e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1608e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1609702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1610702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1611ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1612702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1613702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1614702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1615702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
16164125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1617702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1618702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1619702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
16204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
16211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
16221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
16234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
16241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
163013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
163113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
163213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
163313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
163413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
163603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
163703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
163803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
163913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
164013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
164113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
164313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
164413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
164513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
164613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
164713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
164813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
164913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
165013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
165113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
165213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
165313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
165413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
165513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
165613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
165713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
165813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
165913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
166013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
166113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
16631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
16641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
166513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
166774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
166813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
166913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
16703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
167113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
167313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1674ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
167513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
167613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
167774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
167813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
167913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
168013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
168113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
168213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
168313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
168413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
16854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
168613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
168713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
168813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
168913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
16901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1691a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1692a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
16931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
16941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
16951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
16961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1697a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
16981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
169974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
17001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1701ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
17026905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1703a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
17046905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
17051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1706bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
170774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1708bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1709d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1710d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1711d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1712d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1715d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1716d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
17196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
17206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
17216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
17226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1723d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1724d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1725d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1726d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
172713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
172813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
172913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
173013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
173113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1732b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1733b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
173413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
173513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
173613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1737a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1738a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
17403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
17433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
17443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
17473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
17483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1749