Layer.cpp revision 792e529dee5b6cf839b982b4b06a37fbf1d3e28a
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),
76cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
815cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
85a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
86a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
87a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
88a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
8965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9004839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
9104839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mSingleBufferMode(false)
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
93a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
9549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
994125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1004125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1014125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
102231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
103231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
127e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
128e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
130bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
131b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
132b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
133b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
134b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
135b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
136bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
137399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
139b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1407f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1417f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1427f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
14319e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
144303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1456905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14996f0819f81293076e652792794a961543e6750d7Mathias Agopian
1504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
151cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
152cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
153cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
154921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian
15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
162c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
16313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
16613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
16713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1706b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1726b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
174a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
175a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
176a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
177a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
178a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
179a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
180a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
181a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
182a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
183a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
184a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
185a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
186a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
187a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
188a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
189a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1906b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
191ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
192a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
193a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
194a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
195a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
1966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
199579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
200579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2016b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
204a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
212a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
213a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItems.editItemAt(0) = item;
2197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2246b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
226399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
227399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
228399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
229399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
230399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
231399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
232399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2336710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2346710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2356710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
237e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    sp<Client> c(mClientRef.promote());
238e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    if (c != 0) {
239e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos        c->detachLayer(this);
240e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    }
241bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
24248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
243cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
24413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
25013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
25113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
25213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
25313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
25613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
25713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
25813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
26113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
26213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
26703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
2797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
2807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
2817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
2827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
2837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
2857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
2867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
2877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
2887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
2907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
2927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
2937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
303582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
304582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
305b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
306b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
313a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
314a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
315a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
316f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
317f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
318a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
319f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
320a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
321a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
322a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
323f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
324a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
326f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
327f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
328f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
329f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
330f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
331f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
332f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
333f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
334f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
335f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
336f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
337f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
338f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
339f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
34013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3426c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3436c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3446c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3456c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3466c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3516c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3526c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3556b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3586b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
36413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3666b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3676b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3686b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3696b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3700e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3710e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3720e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3730e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3740e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3750e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3760e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
38128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
38228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
38328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
38428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
38528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
388f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
389f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
390f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3956b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
396f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
397f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
398f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
399f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
400f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
401f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
402f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
403f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
404f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4051440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
4061440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
4071440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4081440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4091440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
4101440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4111440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
4121440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
413f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
414f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
415f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
416f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
417f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
42013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
4217b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
4227b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
4237b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
4247b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
4257b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
4267b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4277b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4287b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
4297b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4307b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4317b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
43313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
43513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
436f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
43713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4386b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
4396b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
4406b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
44113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
442f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
443f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
444f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
445f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
44813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
44913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
45013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
45113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
45213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
45313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
45413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
458a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
460a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4613e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4623e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
463a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
464dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
465dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
466dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
467dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
46813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4704125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
47113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
47213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
47313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
47413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
47513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
47613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
47713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4786c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4796c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4806c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4816c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4826c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4836c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
48428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
48528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
48628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
48728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
48828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
48928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
49028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
4916c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
4926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
4936c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
4946c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
4956c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
4966c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
4976c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
4986c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
4996c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5006c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
50313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
50413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
5059f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
5069f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
50729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
50829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
50929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
51029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
51129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
51229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
51329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
51429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
51529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
516c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
517c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
518c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
519c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
520c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
521c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
522c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
5231440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
524c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
525c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
526c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
527c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
5281440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
5291440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
5301440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
5311440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
5321440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
5331440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
5341440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
5351440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
536c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
537c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
5381440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
539c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
54029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
54129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
54213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
54313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
54413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
5453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
546a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
54713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
548a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
549a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
550a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
552d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
55313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
55413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
55513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
55813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
55913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
56013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
561db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
562ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
563399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
564399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
565399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
566399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
567399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
568399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
569399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
570c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
571dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
572c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
573d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
574c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
575d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
576d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
577d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
578d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
57903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
580bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
582c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
583dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
584dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
585dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
586dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
587dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
588c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
589c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
590c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
59103414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
59203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
59303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
59403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
59503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
59603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
59703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
59803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
59903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
60003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
60103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
60203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
60303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
60403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
60503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
60603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
60703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
60803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
60903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
61003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
61113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
61213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
61313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
616c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
61813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
619c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
620c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
621c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
62213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
62313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
624c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
625c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
627c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
628c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
629c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
635179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
636179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
637179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
638179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
639179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
640179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
641179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
642179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
643179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
644f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
645f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
646179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
647179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
64813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
64913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
650179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
652179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
653179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
654179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
655179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6561b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
657179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
660a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
66197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
66297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
663bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
664bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
66597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
666dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
667dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
668dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
669dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
670dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
671dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
672875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
673875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
674dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
675cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
676eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
677cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
678cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
679cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
680bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
681bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
682cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
683c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
684c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
685c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
686c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
687c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
688c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
689c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
690c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
691c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
692c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
693c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
694c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
695c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
696c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
697c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
698c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
699c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
700c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
701c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
702c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
703c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
704c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
705c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
706c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
707c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
708c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
709c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
711cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
71249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
71349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
71449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
71549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
71649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
718875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
719a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
720c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
721875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
725c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
726c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
727c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
72813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
72919733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
730c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
73119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
73219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
73313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
73413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
73513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
73613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
73913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
740c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
741c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
744c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
755c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
767875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
768875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
769ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
770ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
771ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
772ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
773ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
775875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7764125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7775cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
778875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7811681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7821681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7831681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7841681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7851681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
7861681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
7871681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
7881681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
7891681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
7901681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
7911681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
792cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
793cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
794cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
795cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
796cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
797cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
7987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
799cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
8007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
801cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
802cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
803cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
804cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
805cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
8067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
807cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
808cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
809cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
810cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
8117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
8127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
821ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
822ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
823ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
824ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
825ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
826ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
827ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8285773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
829a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
830a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
831ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
8325773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
8335773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
8345773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
835dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
8365773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
8375773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
838dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
839ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
840ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
845c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
846c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
8481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
849c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
850c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
8566c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
857f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
859ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
860ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
861ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
862ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
863ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8655cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
868ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8694125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
870a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
871a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
872a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
873db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
874a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
875db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
876a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
877a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
878a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8794125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
880a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
881a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
882231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
883231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
884231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
885231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
886231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
887231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
8887a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
8897a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
890a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
8917a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
8927a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
8937a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
894b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
90313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
90413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
90513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
91013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
91313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
91413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
91813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
91913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
92013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
92113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
92313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
92413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
92513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
92613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
9287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
9297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
9307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
9337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
9347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
9357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
9367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
9377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
9387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
9397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
9407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
9417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
9427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
9433bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
9443bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
9453bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
946cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
947cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
948cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
949cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
950cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
951cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
952cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
9537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
9547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
9567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
9577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
9587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
9597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::popPendingState() {
9627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto oldFlags = mCurrentState.flags;
9637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState = mPendingStates[0];
964cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
9657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            (mCurrentState.flags & mCurrentState.mask);
9667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
9687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
9697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
9707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozabool Layer::applyPendingStates() {
9717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
9727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
9737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
9747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
9757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
9767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
9777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
9787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
9797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
9827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
9837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
984cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
985cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
986cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
987cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
988cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
989cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
990cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
991cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
992cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
993cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
994cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
9957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
9967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
9977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
9987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
9997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
10017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
10027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1003792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1004792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
10057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
10067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
10077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            popPendingState();
10087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
10097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
10107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
10137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
10147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
10157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
10167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
10177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
10207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
10217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1024cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
1025cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1026cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
1027cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (headFrameNumber >= point->getFrameNumber()) {
1028cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1029cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
10307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
10341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
10367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
10377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!applyPendingStates()) {
10387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
10397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
10407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
10411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
10421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
10451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1046a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1047a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1048cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
10499d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
10506905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1051419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1052419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1053419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1054419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
10561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
10571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
10581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
10591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
10601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
10611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
10621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
10631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
10641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
10651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
10661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
10671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
10681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
10691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
10701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
10711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
10721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
10731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
10741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
10751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
10761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
10771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
10781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
10791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
10801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
10811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
10821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
10831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
1084a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
10852a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
10862a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1087bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
10881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1090cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
10910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
10920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
10941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
10950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
10969e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
109713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
10980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
10990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
11000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
11010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
11020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
11030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
11040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
11059e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
11069e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
11079e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
11089e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
11090cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
11100cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
11110cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
11120cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
11130cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
11181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
11191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
112013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
112313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
112613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
112813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
112913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
11331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
11341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1146a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
114713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
114813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
114913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
115213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
115313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
115513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
115613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
115713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
115913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
11607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
116113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
116213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
116313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
11697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
11787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
11877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
11957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
12002ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
12017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
120213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
120313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
120413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
120513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
120613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
120713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
120813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
120913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
121013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
12117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
12127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
121313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
121413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
121813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
12217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
122413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
122613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
122713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
122813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
122913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
123013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
12317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
123213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
123313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1234a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1235a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
12367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
12377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
12387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
12397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
12407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
12417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
12427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
12437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1244792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1245792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
12467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
12477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1249ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1250ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1251ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1252ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1253ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1254ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1255ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1256ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1257ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1258ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1259ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1260ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12656b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1266063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mSidebandStreamChanged || mSingleBufferMode) {
1267d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1268d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1269d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
12706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
12710eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
12720eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
12730eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
12740eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
12756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
12766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
12770eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12780eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
12790eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
12800eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
12810eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
12820eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
12830eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
12840eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
12850eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
12866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
12876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
12884d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
12894d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1290063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
129199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
129299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1293d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1294d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1295bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
129682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
129782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1298bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1299789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
130082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
130182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
130282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
130382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
130482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
130582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
130682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1307d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
130882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1309789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
131082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
131182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
131282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
131382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
131482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
131582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
131682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
131782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
131882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1319d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1320d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1321d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1322d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1323da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
132413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
132513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1326afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1327da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1328da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
13294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1333399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1334399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1335399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
133612e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
133712e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
133812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
133912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
13405bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
13415bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
13425bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
13435bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1344399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1345399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
13464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1347063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos    if (mQueuedFrames > 0 || mSingleBufferMode) {
134899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
134999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
135099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
135199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
135299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
135399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
13544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
13554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
135699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
135799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1358351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
13594125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
13604125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1361351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1362db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1363bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
13642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
13652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
13662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
13671681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
13682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
13691681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
13702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
13711681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
13721681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
13732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
13742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
137611611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
13772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
13782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
13792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
13822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
13832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
13852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
13862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
13872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
13882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
13892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
13912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
13922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
13932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
13942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
13952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
13962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
13972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
13982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
13992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
14002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
14012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
14032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
14042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
14052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
14062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
14072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
14082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
14092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
14112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
14122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
14156905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
14162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
14172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
14186905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
14192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
14202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
14212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
14222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
14232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
14242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
14252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
14262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
14272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
14282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
14292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
14302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
14312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
14322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
14332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14351681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
14362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
14372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
14384824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
14391681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
14401681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
14412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
14422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
14432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
14442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14452ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
14462ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
14472ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
14482ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
14492ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
14502ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
14512ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
14526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
14546c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
14556c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
14566c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
14576c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
14586c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
14596c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
14606c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
14616c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
14622ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
14632ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
14642ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
14652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
14662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
14672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
14682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14691681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
14701681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
14712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1473cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1474cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1475cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1476cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1477cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1478cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1479cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
14807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1481cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1482cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1483cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
14847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
14857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1486cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
14877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1488cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1489cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1490cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1491cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1492cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1493cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1494cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1495cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1496cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1497cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1498cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
14997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1500a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1501a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1502cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
1503cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
1504cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
1505cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1506cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1507063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1508063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
1509063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in single
1510063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1511063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
151241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1513063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
1514cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
15151585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
15161585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
15171585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
15181585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15191585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1520ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1521ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1522ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1523063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1524063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1525063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1526063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1527063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1528ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
152965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
153065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
153165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
153265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
153365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1534063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
153565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
153665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
153765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
153865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
153965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
154065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
154165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
154265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
154365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
154465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
154565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
154665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
15471585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15481585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1549063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1550063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1551ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1552ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1554ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1555ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1556ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1557ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1558ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1559ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1560ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1561ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15626b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
15636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
15646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1565ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
15661585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
15671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1568063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1569063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                || mSingleBufferMode) {
15701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
15711585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
15721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
15731585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
15764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1577a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1578d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1579351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1580bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1581e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1582e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
15834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1584e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1585da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
15864824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1587702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1588e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
15892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
15902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1591ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
15922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1593702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1594bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1595bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1596bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1597702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1598702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1599702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1600702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1601702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1602702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1603702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1604ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1605702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1606702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1607702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1608e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1609e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1610702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1611702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1612ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1613702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1614702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1615702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1616702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
16174125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1618702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1619702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1620702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1621cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1622cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1623cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
1624cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
1625cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
1626cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1627cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
1628cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
1629cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
1630cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
1631cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
1632cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
1633cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
1634cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
1635cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1636cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1637cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1638cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
1639cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
1640cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
1641cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1642cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1643cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1644cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
16454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
16461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
16471c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
16484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
16491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
165513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
165613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
165713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
165813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
165913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
166013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
166103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
166203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
166303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
166413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
166513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
166613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
166713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
166813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
166913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
167013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
167113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
167213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
167313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
167413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
167513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
167613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
167713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
167813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
167913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
168013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
168113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
168213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
168313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
168413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
168513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
168613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
16881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
16891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
169013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
169274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
169313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
169413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
16953e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
169613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
16972ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
169813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1699ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
170013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
170113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
170274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
170313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
170413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
170513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
170613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
170713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
170813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
170913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
17104125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
171113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
171213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
171313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
171413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
17151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
17181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
17191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
17201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
17211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
17231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
172474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
17251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1726ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
17276905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1728a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
17296905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
17301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1731bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
173274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1733bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1734d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1735d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1736d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1737d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1740d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1741d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
174225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
174325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
17446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
17456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
17466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
17476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1748d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1749d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1750d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1751d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
175213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
175313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
175413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
175513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
175613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1757b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1758b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
175913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
176013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
176113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1762a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1763a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
17653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
17683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
17693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
17723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
17733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1774