Layer.cpp revision 063121849890da78b1ad7fb96c54c795de5d1fd6
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),
8965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mUpdateTexImageFailed(false)
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
9349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
974125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
984125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
994125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
100231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
101231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
125e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
126e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
128bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
129b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
130b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
131b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
132b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
133b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
135399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
137b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1387f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1397f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1407f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
14119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
142303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1436905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian
1484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
153921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1546547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
161c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
16213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
16313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
16513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
16613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::markSyncPointsAvailable(const BufferItem& item) {
1707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto pointIter = mLocalSyncPoints.begin();
1717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (pointIter != mLocalSyncPoints.end()) {
1727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if ((*pointIter)->getFrameNumber() == item.mFrameNumber) {
1737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            auto syncPoint = *pointIter;
1747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            pointIter = mLocalSyncPoints.erase(pointIter);
1757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
1767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mAvailableFrames.push_back(std::move(syncPoint));
1777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
1787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ++pointIter;
1797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
1807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
1827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1836b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
187a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
188a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
189a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
190a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
191a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
192a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
193a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
194a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
195a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
196a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
197a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
198a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
199a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
200a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
201a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
202a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
204ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
205a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
206a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
207a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
208a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
2117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    markSyncPointsAvailable(item);
2127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
21399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
214579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
215579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2166b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItems.editItemAt(0) = item;
2347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
239a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    markSyncPointsAvailable(item);
2416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
243399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
244399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
245399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
246399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
247399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
248399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
249399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
25313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
254bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
25548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
256cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
25713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
25813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
26213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
2927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
2937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
2947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
2957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
2967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
2987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
2997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
316582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
317582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
318b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
319b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
32313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
326a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
327a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
328a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
329f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
330f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
331a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
332f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
333a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
334a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
335a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
336f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
337a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
339f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
340f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
341f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
342f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
343f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
344f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
345f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
346f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
347f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
348f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
349f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
350f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
351f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
352f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
35313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3586c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3646c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3656c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
36613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
36713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3686b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
36913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3716b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3796b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3806b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3816b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3826b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3830e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3840e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3850e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3860e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3870e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3880e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3890e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
39328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
39428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
39528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
39628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
39728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
39828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
39913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
40013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
401f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
402f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
403f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
40413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
4086b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
409f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
410f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
411f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
412f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
413f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
414f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
415f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
416f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
417f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4181440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
4191440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
4201440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4211440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4221440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
4231440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4241440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
4251440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
426f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
427f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
428f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
429f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
430f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
43313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
4347b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
4357b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
4367b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
4377b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
4387b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
4397b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4407b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4417b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
4427b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4437b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4447b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
44513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
44813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
449f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
45013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4516b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
4526b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
4536b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
45413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
455f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
456f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
457f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
458f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
46313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
46413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
471a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
47213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
473a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4753e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
476a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
477dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
479dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
480dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
48113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4834125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
48413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
48513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
48613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
48713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
48813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
48913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
49013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4916c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4936c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4946c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4956c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4966c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
49728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
49828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
49928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
50028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
50128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
50228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
50328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
5046c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5056c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5066c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5076c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5086c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5096c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5106c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5116c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5126c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5136c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
5189f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
5199f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
52029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
52129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
52229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
52329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
52429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
52529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
52629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
52729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
52829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
531c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
533c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
534c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
535c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
5361440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
537c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
538c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
539c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
540c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
5411440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
5421440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
5431440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
5441440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
5451440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
5461440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
5471440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
5481440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
549c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
550c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
5511440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
552c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
55329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
55429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
55513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
5583e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
559a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
56013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
561a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
562a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
563a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
565d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
56713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
57113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
57213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
57313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
574db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
575ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
576399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
577399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
578399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
579399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
580399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
581399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
582399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
583c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
584dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
585c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
586d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
587c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
588d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
589d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
590d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
591d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
59203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
593bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5941df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
595c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
596dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
597dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
598dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
599dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
600dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
601c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
602c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
603c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
60403414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
60503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
60603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
60703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
60803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
60903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
61003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
61103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
61203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
61303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
61403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
61503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
61603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
61703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
61803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
61903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
62003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
62103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
62203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
62303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
62413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
62613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
629c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
63013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
632c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
633c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
634c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
63513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
637c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
638c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
639c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
640c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
641c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
642c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
646a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
648179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
649179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
650179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
651179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
652179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
653179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
654179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
655179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
656179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
657f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
658f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
659179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
660179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
66113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
663179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
665179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
666179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
667179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
668179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
670179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
67597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
676bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
677bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
67897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
679dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
680dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
681dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
682dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
683dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
684dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
685875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
686875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
687dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
688cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
689eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
690cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
691cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
692cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
693bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
694bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
695cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
696c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
697c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
698c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
699c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
700c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
701c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
702c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
703c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
704c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
705c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
706c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
707c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
708c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
709c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
711c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
712c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
713c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
714c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
715c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
716c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
717c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
718c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
719c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
720c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
721c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
722c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
723c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
724cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
72549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
72649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
72749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
72849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
72949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
730a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
731875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
732a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
733c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
734875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
738c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
739c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
740c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
74113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
74219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
743c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
74419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
74519733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
753c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
754c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
757c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
768c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
76913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
77113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
780875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
781875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
782ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
783ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
784ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
785ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
786ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
788875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7905cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
791875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7941681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7961681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7971681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7981681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
7991681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
8001681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
8011681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
8021681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
8031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
8041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
8057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) {
8067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    uint64_t headFrameNumber = 0;
8077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    {
8087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
8097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!mQueueItems.empty()) {
8107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            headFrameNumber = mQueueItems[0].mFrameNumber;
8117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
8127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            headFrameNumber = mLastFrameNumberReceived;
8137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
8147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
8157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
8167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (point->getFrameNumber() <= headFrameNumber) {
8177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        point->setFrameAvailable();
8187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    } else {
8197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLocalSyncPoints.push_back(std::move(point));
8207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
8217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
8227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
831ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
832ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
833ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
834ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
835ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
836ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
837ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8385773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
839a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
840a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
841ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
8425773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
8435773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
8445773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
845dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
8465773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
8475773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
848dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
849ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
850ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
855c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
856c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
8581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
859c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
860c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
8666c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
867f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
869ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
870ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
871ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
872ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
873ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8755cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
878ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8794125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
880a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
881a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
882a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
883db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
884a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
885db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
886a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
887a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
888a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
890a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
891a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
892231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
893231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
894231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
895231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
896231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
897231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
8987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
8997a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
900a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
9017a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
9027a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
9037a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
904b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
90513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
91813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
91913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
92013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
92313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
92413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
92513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
92713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
92813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
92913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
93013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
93113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
93213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
93313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
93413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
93513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
93613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
9387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
9397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
9407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mPendingStateMutex);
9437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
9457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
9467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
9477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
9487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
9497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
9507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
9517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
9527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
9537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
9547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
9557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
9567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber);
9587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        handleLayer->addSyncPoint(syncPoint);
9597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mRemoteSyncPoints.push_back(std::move(syncPoint));
9607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
9627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
9637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
9657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::popPendingState() {
9687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto oldFlags = mCurrentState.flags;
9697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState = mPendingStates[0];
9707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
9717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            (mCurrentState.flags & mCurrentState.mask);
9727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
9747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozabool Layer::applyPendingStates() {
9777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mPendingStateMutex);
9787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
9807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
9817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
9827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
9837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
9847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
9857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
9867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
9877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
9907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
9917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
9937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
9947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
9987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
9997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
10007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
10017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            break;
10027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
10037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            popPendingState();
10047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
10057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
10067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
10097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
10107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
10117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
10127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
10137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
10167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
10177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
10207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    Mutex::Autolock lock(mAvailableFrameMutex);
10217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    for (auto frame : mAvailableFrames) {
10227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        frame->setFrameAvailable();
10237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
10271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10281c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
10297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
10307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!applyPendingStates()) {
10317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
10327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
10351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
10381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1039a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1040a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1041cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
10429d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
10436905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1044419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1045419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1046419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ 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",
10481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
10491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
10501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
10511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
10521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
10531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
10541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
10551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
10561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
10571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
10581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
10591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
10601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
10611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
10621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
10631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
10641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
10651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
10661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
10671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
10681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
10691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
10701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
10711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
10721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
10731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
10741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
10751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
10761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
1077a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
10782a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
10792a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1080bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
10811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1083cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
10840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
10850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
10871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
10880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10899e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
109013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
10910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
10920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
10930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
10940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
10950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
10960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
10970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
10989e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
10999e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
11009e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
11019e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
11020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
11030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
11040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
11050cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
11060cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
110713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
110813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
110913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
111013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
11111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
11121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
111313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
111813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
111913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
112213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
112313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
11261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
11271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
112813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
112913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
113213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1138a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1139a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
114513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
114613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
114813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
114913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
115213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
11537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
115513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
115613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
115713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
115913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
116013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
116113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
11627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
116313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
11717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
11807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
11887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
11932ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
11947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
120013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
120113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
120213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
120313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
12047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
12057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
120613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
120713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
120813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
120913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
121013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
121113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
121213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
121313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
12147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
121813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
12247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
122613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1227a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1228a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
12297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
12307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
12317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
12327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
12337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
12347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
12357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
12367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
12377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
12387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1240ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1241ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1242ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1243ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1244ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1245ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1246ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1247ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1248ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1249ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1250ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1251ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12566b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1257063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mSidebandStreamChanged || mSingleBufferMode) {
1258d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1259d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1260d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
12616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
12620eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
12630eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
12640eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
12650eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
12666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
12676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
12680eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12690eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
12700eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
12710eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
12720eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
12730eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
12740eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12750eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
12760eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
12776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
12786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
12794d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
12804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1281063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
128299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
128399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1284d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1285d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1286bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
128782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
128882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1289bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1290789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
129182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
129282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
129382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
129482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
129582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
129682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
129782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1298d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
129982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1300789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
130182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
130282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
130382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
130482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
130582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
130682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
130782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
130882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
130982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1310d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1311d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1312d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1313d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1314da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
131613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1317afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1318da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1319da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
13204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1324399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1325399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1326399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
132712e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
132812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
132912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
133012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
13315bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
13325bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
13335bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
13345bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1335399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1336399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
13374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1338063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mQueuedFrames > 0 || mSingleBufferMode) {
133999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
134099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
134199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
134299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
134399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
134499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
13454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
13464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
134799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
134899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1349351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
13504125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
13514125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1352351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1353db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1354bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
13552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
13562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
13572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
13581681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
13592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
13601681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
13612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
13621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
13631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
13642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
13652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
136711611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
13682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
13692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
13702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
13732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
13742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
13762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
13772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
13782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
13792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
13822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
13832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
13852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
13862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
13872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
13882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
13892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
13902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
13912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
13922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
13942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
13952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
13962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
13972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
13982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
13992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
14002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
14022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
14032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
14066905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
14072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
14082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
14096905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
14102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
14112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
14122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
14132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
14142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
14152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
14162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
14172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
14182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
14192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
14202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
14212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
14222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
14232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
14242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14261681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
14272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
14282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
14294824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
14301681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
14311681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
14322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
14332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14352ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14362ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
14372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
14382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
14392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
14402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
14412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
14422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
14436c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14446c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
14456c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
14466c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
14476c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
14486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
14496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
14506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
14516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
14532ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
14542ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
14552ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
14572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
14582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
14592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14601681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
14611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
14622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1463a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        uint64_t maxFrameNumber = 0;
14647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t headFrameNumber = 0;
1465a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        {
1466a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            Mutex::Autolock lock(mQueueItemLock);
1467a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            maxFrameNumber = mLastFrameNumberReceived;
14687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (!mQueueItems.empty()) {
14697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                headFrameNumber = mQueueItems[0].mFrameNumber;
14707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        bool availableFramesEmpty = true;
14747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
14757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
14767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            availableFramesEmpty = mAvailableFrames.empty();
14777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!availableFramesEmpty) {
14797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
14807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            bool matchingFramesFound = false;
14817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            bool allTransactionsApplied = true;
14827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            for (auto& frame : mAvailableFrames) {
14837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                if (headFrameNumber != frame->getFrameNumber()) {
14847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
14857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
14867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
14877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                allTransactionsApplied &= frame->transactionIsApplied();
14887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (matchingFramesFound && !allTransactionsApplied) {
14907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mFlinger->signalLayerUpdate();
14917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                return outDirtyRegion;
14927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1493a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1494a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1495063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1496063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
1497063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in single
1498063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1499063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
150041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1501063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
1502063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                maxFrameNumber);
15031585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
15041585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
15051585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
15061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1508ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1509ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1510ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1511063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1512063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1513063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1514063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1515063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1516ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
151765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
151865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
151965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
152065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
152165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1522063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
152365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
152465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
152565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
152665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
152765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
152865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
152965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
153065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
153165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
153265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
153365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
153465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
15351585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15361585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1537063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1538063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1539ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1540ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1542ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1543ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1544ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1545ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1546ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1547ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1548ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1549ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
15516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
15526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1553ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15541585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
15551585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1556063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1557063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                || mSingleBufferMode) {
15581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
15617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (!availableFramesEmpty) {
15627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            Mutex::Autolock lock(mAvailableFrameMutex);
15637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber();
15647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            while (!mAvailableFrames.empty() &&
15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    frameNumber == mAvailableFrames.front()->getFrameNumber()) {
15667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mAvailableFrames.pop_front();
15677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
15687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
15697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
15701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1572a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
15734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1575d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1576351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1577bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1578e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1579e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
15804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1581e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1582da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
15834824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1584702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1585e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
15862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
15872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1588ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
15892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1590702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1591bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1592bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1593bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1594702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1595702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1596702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1597702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1598702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1599702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1600702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1601ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1602702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1603702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1604702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1605e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1606e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1607702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1608702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1609ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1610702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1611702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1612702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1613702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
16144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1615702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1616702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1617702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
16184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
16191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
16201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
16214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
16221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
162813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
163013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
163113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
163213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
163313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
163403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
163503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
163603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
163713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
163813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
163913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
164013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
164113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
164313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
164413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
164513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
164613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
164713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
164813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
164913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
165013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
165113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
165213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
165313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
165413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
165513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
165613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
165713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
165813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
165913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
16611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
16621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
166313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
166574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
166613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
166713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
16683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
166913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
167113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1672ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
167313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
167413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
167574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
167613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
167713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
167813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
167913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
168013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
168113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
168213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
16834125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
168413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
168513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
168613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
168713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
16881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1689a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1690a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
16911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
16921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
16931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
16941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1695a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
16961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
169774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
16981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1699ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
17006905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1701a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
17026905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
17031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1704bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
170574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1709d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1710d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1713d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1714d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
17176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
17186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
17196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
17206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1721d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1722d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1723d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1724d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
172513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
172613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
172713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
172813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
172913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1730b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1731b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
173213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
173313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
173413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1735a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1736a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
17383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
17413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
17423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
17453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
17463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1747