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
179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza//#define LOG_NDEBUG 0
189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#undef LOG_TAG
199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#define LOG_TAG "Layer"
201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
211c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
29a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
33399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
373330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
399cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h>
4190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
450f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
47b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
511b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
52875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
53875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
54c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza#include <mutex>
55c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
7013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
7113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
7213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
7313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStateMutex(),
757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStates(),
76a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
77399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
78a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
79933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
80c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        mOverrideScalingMode(-1),
81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
82cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
834d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
8482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
8513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
875cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifndef USE_HWC2
8940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        mIsGlesComposition(false),
9040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
9113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
9213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
9303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
94a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
95a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
96a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
97a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
9865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9904839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
10082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mAutoRefresh(false),
10182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mFreezePositionUpdates(false)
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
107a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
10949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1134125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1154125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
116231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
117231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1263dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.active.transform.set(0, 0);
127b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop.makeInvalid();
128b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop.makeInvalid();
1294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
152e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
153e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
155bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
156b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
157b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
158b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
159b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
160ce796e78a57018f186b062199c75d94545318acaPablo Ceballos    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName,
161ce796e78a57018f186b062199c75d94545318acaPablo Ceballos            this);
162bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
163399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
165b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1667f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1677f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1687f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
16919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
170303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1716905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
174b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17596f0819f81293076e652792794a961543e6750d7Mathias Agopian
1764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1778ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1788ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1798ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1808ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1818ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
182cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
183cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
184cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
185c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    for (auto& point : mLocalSyncPoints) {
186c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        point->setFrameAvailable();
187c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
188921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
19096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
19196f0819f81293076e652792794a961543e6750d7Mathias Agopian
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
2009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
2019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
2029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
2039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
204c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
20813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
2119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
225a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
226a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
231a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
232a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
234ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
235a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
236a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
237a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
238a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
242579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
243579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2446b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
247a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
255a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
256a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2614d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
2627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
269399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
270399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
271399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
272399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
273399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
274399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
275399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2776710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2786710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
280bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
28148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
282cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
3187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
3197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
3207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
3217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
3227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
3237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
3247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
3257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
343582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
344b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
345b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
35113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
352a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
353a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
354a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
355f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
356f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
357a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
358f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
359a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
360a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
361a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
362f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
363a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
365f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
366f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
367f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
368f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
369f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
370f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
371f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
372f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
373f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
374f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
375f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
376f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
377f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
378f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
37913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3816c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3826c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3836c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3846c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3856c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
387b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
388b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
389b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3916c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3956b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
39713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3986b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
39913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
400b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
40113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
4021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
40313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
4066b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
4076b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
4086b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
4096b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
4100e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4110e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
412b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
413b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
4140e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
4150e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4163dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
417acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
418acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
419acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
420b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
421b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
422acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
423acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
424acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4253dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
42728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
42828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
42928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
43028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
43128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
43228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
43613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
437f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
438f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
439f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
440acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
442acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
443acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
446021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
447021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
448acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
449021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransformOrient =
450021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
451acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
452acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
453acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
454acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
45513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
456acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
4570f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        invTransform = (Transform(invTransformOrient) * Transform(invTransform))
4580f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos                .getOrientation();
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
462acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
465acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
466acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
469acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
476acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
477acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
478acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
479acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
48013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
481acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
482acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
483acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
48413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
485acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
486acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
487acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
488acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
489acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
490acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
491acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
492acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
493acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
5024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
5034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
505a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
5099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
512a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
5133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5233e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
524a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
525dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
526dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
527dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
529dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5424125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
54313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
54413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
54513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
54813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
54913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
55013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
552b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
553b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5543dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
556acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
558acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
560acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
561acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
56251450039e2fd266b31f33dfd1b4353bc1b0b145aPablo Ceballos        activeCrop = s.active.transform.inverse().transform(activeCrop, true);
56328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
56428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
56528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
56628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
56728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
56828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
569acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
570acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
571acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5776c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5786c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5796c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5806c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5813dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
582b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
583b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
584acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
585acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
586acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
588acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
589acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
590acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
594e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
595e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
596e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                mName.string(), transformedFrame.left, transformedFrame.top,
597e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                transformedFrame.right, transformedFrame.bottom,
598e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
599e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
600e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.displayFrame = transformedFrame;
601e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
605e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
606e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
607e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top,
608e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(),
609e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                static_cast<int32_t>(error));
610e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
611e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.sourceCrop = sourceCrop;
612e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
6139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
6169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
6179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
6209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
6219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
6229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
624acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(hw->getViewport(), &frame)) {
625acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
626acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
6309f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
6319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6329f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
63329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
63429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
63529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
63629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
63729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
63829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
63929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
64029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
64129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6423dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
643c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
644c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
645c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
646021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
647021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
648c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
649021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransform =
650021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
651c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
652c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
653c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
654c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
655c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
656c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6570f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        transform = Transform(invTransform) * transform;
658c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
65929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
66029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
66113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
67413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
67513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
6763e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
677a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
67813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
679a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
681a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
682a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
7039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
7159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7170f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Sideband layers
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
7190f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Sideband);
7200f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Sideband composition", mName.string());
7210f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7270f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7300a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // Client layers
7310a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mHwcLayers[hwcId].forceClientComposition ||
7320a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
7330f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Client composition", mName.string());
7349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7350f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7360f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7370f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7380a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // SolidColor layers
7390a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mActiveBuffer == nullptr) {
7400a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        setCompositionType(hwcId, HWC2::Composition::SolidColor);
741c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
742c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // For now, we only support black for DimLayer
7430a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        error = hwcLayer->setColor({0, 0, 0, 255});
7440a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        if (error != HWC2::Error::None) {
7450a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
7460a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7470a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        }
748c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
749c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // Clear out the transform, because it doesn't make sense absent a
750c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // source buffer
751c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        error = hwcLayer->setTransform(HWC2::Transform::None);
752c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        if (error != HWC2::Error::None) {
753c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza            ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
754c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
755c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        }
756c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
7570a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        return;
7580a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    }
7590a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza
7600f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Device or Cursor layers
7610f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (mPotentialCursor) {
7620f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Cursor composition", mName.string());
7630f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Cursor);
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7680f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7690f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7700f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
7710f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (error != HWC2::Error::None) {
7720f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7730f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                mActiveBuffer->handle, to_string(error).c_str(),
7740f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                static_cast<int32_t>(error));
7750f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
7784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
779d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
788db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
78940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
790ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
791399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
792399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
793399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
794399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
795399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
796399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
797399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
798c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
8009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
8029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
8039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
8049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
8059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
8069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
8079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
8109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
811dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
8129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
8139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
8149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
815b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
816b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
8179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
8199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
820baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
8219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
822b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
823b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
824acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
8259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
8269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
8279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
8299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
8309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
8319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
8329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
8339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
8349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
8359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
836c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
837d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
838c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
839d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
840d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
841d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
842d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
84303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
844bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8451df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
846c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
847dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
848dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
849dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
850dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
851dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
852c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
853c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
854c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
85503414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
85603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
85703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
85803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
85903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
86003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
86103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
86203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
86303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
864b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
865b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
86603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
86703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
86803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
8693dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(bounds));
87003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
871b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
872b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
873acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
87403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
87503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
87603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
8779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
87803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
884c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
887c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
888c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
889c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
892c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
893c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
894c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
895c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
896c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
897c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8991c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
901a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
903179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
904179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
905179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
906179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
907179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
908179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
909179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
910179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
911179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
912f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
913f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
914179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
915179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
91613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
91713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
918179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
9194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
920179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
921179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
922179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
923179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
9241b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
925179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
928a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
92997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
93097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
931bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
932bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
93397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
934dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
935dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
936dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
937dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
938dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
939dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
940875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
941875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
942dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
943cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
944eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
945cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
946cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
947cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
948bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
949bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
950cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
951c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
952c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
953c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
954021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the code below applies the primary display's inverse transform to
955021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the texture transform
956c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
957c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
958c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
959c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
960c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
961c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
962c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
963c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
964021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos            uint32_t transform =
965021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                    DisplayDevice::getPrimaryDisplayOrientationTransform();
966c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
967c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
968c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
969c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
970c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
971c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
972c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
973c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
974c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
975c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
976c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
977c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
978c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
979c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
980c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
981cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
98249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
98349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
98449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
98549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
98649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
987a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
988875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
989a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
990c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
991875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
995c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
996c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
997c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
99919733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
1000c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
100119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
100219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1010c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
1011c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
10121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1014c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
1025c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
1030acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
1031acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1032b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1033acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
1034b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
1035acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1036acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1037acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
1038acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
1039acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1040acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1041acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1048875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1049875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1050ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1051ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1052ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1053ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1054ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
105513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1056875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10574125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10585cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1059875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
106013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
106113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1087ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
1088ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // If we're querying the composition type for a display that does not
1089ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // have a HWC counterpart, then it will always be Client
1090ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return HWC2::Composition::Client;
1091ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
1093ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        ALOGE("getCompositionType called with an invalid HWC layer");
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
11009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
11019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
11029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
11039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
11049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
11059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
11069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
11089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
11099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
11109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
11119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
11129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
11139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
11149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
11159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11161681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
11171681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
11181681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
11191681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
11201681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
11211681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
11221681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
11231681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
11241681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
11251681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
11261681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1127c5da271eec001da9e11a2786f2618a45257439c3Dan Stozabool Layer::latchUnsignaledBuffers() {
1128c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool propertyLoaded = false;
1129c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool latch = false;
1130c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static std::mutex mutex;
1131c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    std::lock_guard<std::mutex> lock(mutex);
1132c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (!propertyLoaded) {
1133c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        char value[PROPERTY_VALUE_MAX] = {};
1134c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        property_get("debug.sf.latch_unsignaled", value, "0");
1135c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        latch = atoi(value);
1136c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        propertyLoaded = true;
1137c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1138c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    return latch;
1139c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza}
1140c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
1141cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1142cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1143cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1144cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1145cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1146cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
11477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1148cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
11501ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stozabool Layer::headFenceHasSignaled() const {
11511ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#ifdef USE_HWC2
1152c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (latchUnsignaledBuffers()) {
1153c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        return true;
1154c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1155c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
11561ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
11571ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems.empty()) {
11581ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11591ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11601ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems[0].mIsDroppable) {
11611ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // Even though this buffer's fence may not have signaled yet, it could
11621ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // be replaced by another buffer before it has a chance to, which means
11631ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // that it's possible to get into a situation where a buffer is never
11641ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // able to be latched. To avoid this, grab this buffer anyway.
11651ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11661ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11671ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
11681ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#else
11691ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return true;
11701ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#endif
11711ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza}
11721ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1173cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1174cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1175cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1176cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1177cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1179cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1180cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1181cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1182cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1193ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1194ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1195ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1196ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1197ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1198ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1199ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12005773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1201a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1202a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1203ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
12045773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
12055773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
12065773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1207dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
12085773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
12095773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1210dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1211ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1212ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
121313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
121413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
121513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1217acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1218acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1219acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1220acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1221acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1222acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1223acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1224acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1225acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1226acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1227acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1228acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1229acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1230acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1231acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1232c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1233c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
123413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
12351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1236acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
123713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
123813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1239b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1240b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
124113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
12426c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1243f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
12443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1245acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1246acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1247acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1248acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1249acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1250acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1251acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1252acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1253acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1254acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1255acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1256acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1257b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1258b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1259b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1260b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1261b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1262acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1263acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1264ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1265acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1266acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1267acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1268acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12705cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
127113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
127213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1273ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12744125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1275a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1276a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1277a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1278db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1279a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1280db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1281a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1282a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1283a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12844125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1285a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1286a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1287231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1288231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1289231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1290231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1291231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1292231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12937a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12947a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1295a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12967a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12977a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1299b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
130013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
1301c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
130213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
130413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
130513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
130613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
130813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
130913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
131013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
131113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
131213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
131313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
131413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
131613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
131713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
131813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
131913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
132013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
132113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
132213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
132313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
132413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
132513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
132613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
132713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
132813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
132913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
133013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
133113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
13347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
13357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
13387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
13397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
134092cd24e5f648175944deef5899258981807a9ca4Dan Stoza        sp<IBinder> strongBinder = mCurrentState.handle.promote();
134192cd24e5f648175944deef5899258981807a9ca4Dan Stoza        sp<Handle> handle = nullptr;
134292cd24e5f648175944deef5899258981807a9ca4Dan Stoza        sp<Layer> handleLayer = nullptr;
134392cd24e5f648175944deef5899258981807a9ca4Dan Stoza        if (strongBinder != nullptr) {
134492cd24e5f648175944deef5899258981807a9ca4Dan Stoza            handle = static_cast<Handle*>(strongBinder.get());
134592cd24e5f648175944deef5899258981807a9ca4Dan Stoza            handleLayer = handle->owner.promote();
134692cd24e5f648175944deef5899258981807a9ca4Dan Stoza        }
134792cd24e5f648175944deef5899258981807a9ca4Dan Stoza        if (strongBinder == nullptr || handleLayer == nullptr) {
13487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
13497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
13507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
13527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
13533bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
13543bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
13553bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1356cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1357cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1358cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1359cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1360cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1361cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1362cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
137105289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::popPendingState(State* stateToCommit) {
137205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    auto oldFlags = stateToCommit->flags;
137305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    *stateToCommit = mPendingStates[0];
137405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
137505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            (stateToCommit->flags & stateToCommit->mask);
13767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
138005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosbool Layer::applyPendingStates(State* stateToCommit) {
13817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
138905289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1394cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1395cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1396cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1397cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1398cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1399cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1400cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1401cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1402cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1403cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1404cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
14057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
14067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
140705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
14087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
14097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
14117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
14127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1413792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1414792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
14157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
141705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            popPendingState(stateToCommit);
14187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
14197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
14237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
14247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
14257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
14267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
14277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
14307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
14317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1434cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
14351ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    bool headFenceSignaled = headFenceHasSignaled();
1436cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1437cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
14381ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
1439cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1440cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
14417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
144413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
14451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
14461c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
14477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
144805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    Layer::State c = getCurrentState();
144905289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    if (!applyPendingStates(&c)) {
14507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
14517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
14561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1457a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1458a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1459cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14609d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14616905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1462419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1463b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1464419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1465b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
1466c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                this, getName().string(), mCurrentTransform,
1467c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getEffectiveScalingMode(),
14681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1469b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1470b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1471b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1472b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1473b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1474b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1477b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1478b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1479b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1480b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1481b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1482b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1483b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1484a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14852a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14862a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1487bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1490cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
149182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    const bool resizePending = (c.requested.w != c.active.w) ||
149282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            (c.requested.h != c.active.h);
14930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14949e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
149513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
14960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
14970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
14980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
14990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
15000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
15010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
15020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
15039e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
15049e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
15059e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
15069e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
15070cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
15080cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
15090cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
15100cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
15110cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
151413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
15167d05257585918bd578bc0bc18f32571a48a7304aPablo Ceballos        Layer::State& editCurrentState(getCurrentState());
151782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        if (mFreezePositionUpdates) {
151882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float tx = c.active.transform.tx();
151982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float ty = c.active.transform.ty();
152082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
152182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active.transform.set(tx, ty);
152282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = c.active;
152382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        } else {
152482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = editCurrentState.requested;
152582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
152682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        }
152713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
152813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
153013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
153113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
153213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
153313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
153513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
153613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
153713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
153813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
153913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
15403dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
15413dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
154213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
154313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
154413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1545c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // If the layer is hidden, signal and clear out all local sync points so
1546c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // that transactions for layers depending on this layer's frames becoming
1547c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // visible are not blocked
1548c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    if (c.flags & layer_state_t::eLayerHidden) {
1549c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        Mutex::Autolock lock(mLocalSyncPointMutex);
1550c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        for (auto& point : mLocalSyncPoints) {
1551c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza            point->setFrameAvailable();
1552c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        }
1553c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        mLocalSyncPoints.clear();
1554c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
1555c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza
155613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
155705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    commitTransaction(c);
155813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156105289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::commitTransaction(const State& stateToCommit) {
156205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    mDrawingState = stateToCommit;
1563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
156513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
156613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
156713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
156813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
156913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
157013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
157113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
157213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
157382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carrbool Layer::setPosition(float x, float y, bool immediate) {
15743dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
157513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
157613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
157769663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
157869663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
157969663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
158069663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15813dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
158282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    if (immediate && !mFreezePositionUpdates) {
158382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mCurrentState.active.transform.set(x, y);
158482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    }
158582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    mFreezePositionUpdates = mFreezePositionUpdates || !immediate;
158669663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
158813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
158913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
159013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
159182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr
159213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
159313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
159413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
159513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
159613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
159813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
159913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
160013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
160113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
160213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
160313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
160413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
160513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
16067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
160713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
160813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
160913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
16129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
161313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
16149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
161513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
161613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
161713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
161813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
16197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
162013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
162113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
162213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
162313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
162413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
16253dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
162613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
16277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
162813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
163013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
163113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
16322ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
16337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
163413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
163613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
163713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
163813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
163913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
164013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
164113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
16437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
16447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
164513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
164613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
164713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
164899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
164999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carrbool Layer::setCrop(const Rect& crop, bool immediate) {
1650b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
165113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
165213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
165399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    mCurrentState.requestedCrop = crop;
165499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    if (immediate) {
165599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        mCurrentState.crop = crop;
165699e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    }
16577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
165813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
165913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
166013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1661acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1662b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1663acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1664acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1665b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1666acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1667acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1668acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1669acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
167013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1671c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carrbool Layer::setOverrideScalingMode(int32_t scalingMode) {
1672c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (scalingMode == mOverrideScalingMode)
1673c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        return false;
1674c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    mOverrideScalingMode = scalingMode;
167582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    setTransactionFlags(eTransactionNeeded);
1676c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return true;
1677c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1678c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
1679c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carruint32_t Layer::getEffectiveScalingMode() const {
1680c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (mOverrideScalingMode >= 0) {
1681c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr      return mOverrideScalingMode;
1682c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    }
1683c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return mCurrentScalingMode;
1684c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1685c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
168613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
168713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
168813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
168913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
169013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
16917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
169213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
169313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1694a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1695a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
16967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
16977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
16987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
16997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
17007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
17017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
17027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
17037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1704792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1705792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
17067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
17077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
17087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1709ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1710ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1711ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1712ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1713ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1714ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1715ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1716ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1717ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1718ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1719ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1720ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17256b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1726ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1727d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1728d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1729d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
17306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
17310eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
17320eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
17330eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
17340eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
17356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
17366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
17370eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17380eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
17390eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
17400eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
17410eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
17420eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
17430eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17440eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
17450eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
17466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
17476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
17484d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
17494d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1750ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
175199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
175299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1753e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozabool Layer::onPostComposition() {
1754e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    bool frameLatencyNeeded = mFrameLatencyNeeded;
1755d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1756bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
175782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
175882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1759bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1760789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
176182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
176282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
176382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
176482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
176582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
176682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
176782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1768d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
17699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
17719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
177282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
17739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1774789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
177582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
177682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
177782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
177882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
177982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
178082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
178182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
178282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
178382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1784d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1785d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1786e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return frameLatencyNeeded;
1787d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1788d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
17899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
17919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
17929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
17939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
17949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1795da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
179613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
17979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
17999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
18009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
180113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1802afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
18039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1804da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1805da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
18064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
18091c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1810399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1811399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1812399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
181312e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
181412e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
181512e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
181612e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
18175bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
18185bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
18195bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
18203dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1821399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1822399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
18234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1824ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mQueuedFrames > 0 || mAutoRefresh) {
182599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
182699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
182799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
182899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
182999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
183099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
18314d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
18324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
183399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
183499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
18351ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // If the head buffer's acquire fence hasn't signaled yet, return and
18361ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // try again later
18371ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (!headFenceHasSignaled()) {
18381ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza            mFlinger->signalLayerUpdate();
18391ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza            return outDirtyRegion;
18401ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        }
18411ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1842351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
18434125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
18444125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1845351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1846db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1847bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
18482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
18492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
18502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
18511681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
1852b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            const char* name;
1853c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            int32_t overrideScalingMode;
1854a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr            bool& freezePositionUpdates;
1855b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
18562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
1857b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                    bool& recomputeVisibleRegions, bool stickySet,
1858c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                    const char* name,
1859a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                    int32_t overrideScalingMode,
1860a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                    bool& freezePositionUpdates)
18612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
18621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
1863b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                  stickyTransformSet(stickySet),
1864c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                  name(name),
1865a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                  overrideScalingMode(overrideScalingMode),
1866a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                  freezePositionUpdates(freezePositionUpdates) {
18672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
18682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
187011611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
18712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
18722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
18732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
18762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
18772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
18792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
18802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
18812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
18822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1884c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                int actualScalingMode = overrideScalingMode >= 0 ?
1885c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                        overrideScalingMode : item.mScalingMode;
1886c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
18872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
18882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
18902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
18912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
18922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
18932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
18942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
18952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
18962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
18972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
18992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
19002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
19012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
19022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
19032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
19042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
190539c88e8c7d870486f703408dafd0a62e7420df05Pablo Ceballos                        current.modified = true;
19062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
19082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
19092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
19102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
1912b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
19132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1914b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "            requested={ wh={%4u,%4u} }}\n",
1915b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            name,
19166905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
19172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
1918b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.left,
1919b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.top,
1920b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.right,
1921b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.bottom,
1922b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getWidth(),
1923b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getHeight(),
1924b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.requested.w, front.requested.h);
19252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
19262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19271681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
19282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
19292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
19304824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
1931b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                        ALOGE("[%s] rejecting buffer: "
1932b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1933b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                name, bufWidth, bufHeight, front.active.w, front.active.h);
19342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
19352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
19362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
19372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
19382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
19392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
19402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
19412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
19422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
19432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
19442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
19456c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
19466c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
19476c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
19486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
19496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
19506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
19516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
19526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
19536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
19546c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
19552ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
19562ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
19572ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
195899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                if (front.crop != front.requestedCrop) {
195999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    front.crop = front.requestedCrop;
196099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    current.crop = front.requestedCrop;
196199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    recomputeVisibleRegions = true;
196299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                }
1963a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                freezePositionUpdates = false;
196499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
19652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
19662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
19672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
19682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19691681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1970c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getProducerStickyTransform() != 0, mName.string(),
1971a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                mOverrideScalingMode, mFreezePositionUpdates);
19722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1974cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1975cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1976cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1977cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1978cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1979cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1980cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
19817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1982cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1983cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1984cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
19857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
19867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1987cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
19887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1989cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1990cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1991cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1992cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1993cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1994cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1995cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1996cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1997cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1998cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1999cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
20007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
2001a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
2002a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2003cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
2004cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
2005cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
2006cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2007cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2008063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
2009063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
20103559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in shared
2011063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
2012063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
201341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
2014ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
2015cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
20161585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
20171585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
20181585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
20191585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
20201585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
2021ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
2022ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
2023ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
2024063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
2025063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
2026063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
2027063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
2028063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
2029ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
203065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
203165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
203265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
203365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
203465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
2035063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
203665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
203765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
203865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
203965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
204065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
204165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
204265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
204365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
204465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
204565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
204665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
204765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
20481585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
20491585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
2050063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
2051063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
2052ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2053ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
2055ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
2056ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
2057ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
2058ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
2059ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
2060ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
2061ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
2062ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
20646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
20656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
2066ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
20681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
2069063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
2070ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                || mAutoRefresh) {
20711585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
20721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
20731585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
20741585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
2075a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
2076a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
20774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
2078a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
2079d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
2080351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
2081bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
2082e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
2083e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
20844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
2085e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
2086da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
20874824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
2088702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
2089e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
20902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
20912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
2092ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
20932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
2094702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2095bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
2096bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
2097bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
2098702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
2099702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
2100702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
2101702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
2102702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
2103702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
2104702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
2105ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
2106702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2107702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2108702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
2109e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
2110e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
2111702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
2112702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
2113ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
2114702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
2115702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2116702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2117702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
21184125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
2119702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
2120702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2121702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2122cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2123cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2124cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
2125cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
2126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
2127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
2128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
2129cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
2130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
2131cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
2132cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
2133cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
2134cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2135cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
2136cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2137cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2138cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2139cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
2140cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
2141cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2142cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2143cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2144cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2145cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
21464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
21471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
21481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
21494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
21503dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        outDirtyRegion = (s.active.transform.transform(dirtyRegion));
2151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
215613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
215713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
215813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
215913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
216013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
216113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
216203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
216303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
216403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
216513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
216613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
216713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
216813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
216913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
217013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
217113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
217213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
217313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
217413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
217513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
217613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
217713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
217813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
217913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
218013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
218113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
218213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
218313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
218413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
218513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
218613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
218713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
21891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
21901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
219113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
219374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
219413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
219513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
21963e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
219713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21982ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
219913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2200ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
220113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
220213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
220374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2204acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2205acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
220613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
22089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
22099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
221013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
22119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
221213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
22133dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2214b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2215b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2216b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2217b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
22184125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
221913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
22203dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
22213dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
222213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
22231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2224a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
22261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
22271b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
22281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
22291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2230a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
22311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
223274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
22331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2234ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
22356905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2236a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
22376905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
22381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2239bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
224074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
2241bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2242d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2243d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
2244e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza#ifdef USE_HWC2
2245e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDumpHeader(String8& result) {
2246e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2247e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2248e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Layer name\n");
2249e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("           Z | ");
2250e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Comp Type | ");
2251e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("  Disp Frame (LTRB) | ");
2252e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("         Source Crop (LTRB)\n");
2253e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2254e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2255e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
2256e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2257e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDump(String8& result, int32_t hwcId) const {
2258e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
2259e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        return;
2260e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2261e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2262e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    String8 name;
2263e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mName.length() > 77) {
2264e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        std::string shortened;
2265e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string(), 36);
2266e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append("[...]");
2267e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string() + (mName.length() - 36), 36);
2268e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = shortened.c_str();
2269e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
2270e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = mName;
2271e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2272e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2273e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat(" %s\n", name.string());
2274e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2275e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Layer::State& layerState(getDrawingState());
2276e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
2277e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("  %10u | ", layerState.z);
2278e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%10s | ",
2279e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            to_string(getCompositionType(hwcId)).c_str());
2280e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Rect& frame = hwcInfo.displayFrame;
2281e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top,
2282e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            frame.right, frame.bottom);
2283e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const FloatRect& crop = hwcInfo.sourceCrop;
2284e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top,
2285e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            crop.right, crop.bottom);
2286e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2287e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - - ");
2288e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - -\n");
2289e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
2290e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza#endif
2291e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2292d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2293d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
229482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
229582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2296d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2297d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
229825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
229925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
23006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
23016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
23026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
23036547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2304d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2305d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2306d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2307d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
230840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
230940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        bool* outIsGlesComposition, nsecs_t* outPostedTime,
231040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
231140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outName = mName;
231240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
231340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
231440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifdef USE_HWC2
231540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
231640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
231740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            HWC2::Composition::Client : true;
231840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#else
231940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mIsGlesComposition;
232040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
232140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
232240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
232340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
232440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
2325e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2326e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastd::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
2327e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool forceFlush) {
2328e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::vector<OccupancyTracker::Segment> history;
2329e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush,
2330e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            &history);
2331e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    if (result != NO_ERROR) {
2332e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(),
2333e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                result);
2334e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        return {};
2335e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2336e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return history;
2337e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2338e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2339367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carrbool Layer::getTransformToDisplayInverse() const {
2340367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
2341367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr}
2342367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr
234313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
234413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
234513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
234613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
234713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
2348b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
2349b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
235013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
235113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
235213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
2353a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
2354a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
2355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
23563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
23593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
23603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
23633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
23643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2365