Layer.cpp revision f5702ff8b1919e0a5d342ad04ac486bbcde41461
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),
889d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifndef USE_HWC2
899d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        mIsGlesComposition(false),
909d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#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{
1039d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#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;
1309d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1329d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
1339d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    mCurrentState.alpha = 0xFF;
1349d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#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
1439d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#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();
1479d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
1489d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    nsecs_t displayPeriod =
1499d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1509d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#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;
158468051e20be19130572231266db306396a56402bIrvel    BufferQueue::createBufferQueue(&producer, &consumer, nullptr, true);
159b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
160468051e20be19130572231266db306396a56402bIrvel    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
162399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
164b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
165c9d972065c44860306add0172b5185bd8611f9eeDan Stoza#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
16619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
167303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1686905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
171b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17296f0819f81293076e652792794a961543e6750d7Mathias Agopian
1734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1748ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1758ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1768ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1778ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1788ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
179cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
180cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
181cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
182c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    for (auto& point : mLocalSyncPoints) {
183c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        point->setFrameAvailable();
184c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
185921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
18796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
18896f0819f81293076e652792794a961543e6750d7Mathias Agopian
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1939d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
2009d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
2019d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
2029d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface* layer) {
2039d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (layer) {
2049d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer->onDisplayed();
2059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
2069d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
2079d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
2089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
214468051e20be19130572231266db306396a56402bIrvel        mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
215468051e20be19130572231266db306396a56402bIrvel                item.mGraphicBuffer->getHeight(), item.mFrameNumber);
216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
225a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
226a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
232ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
233a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
234a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
235a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
236a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
23999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
240579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
241579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2426b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
245a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
253a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
254a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2594d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
2607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
267399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
268399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
269399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
270399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
271399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
272399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
273399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
278bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
27948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
280cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
324582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
325582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
326b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
327b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
334a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
335a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
336a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
337f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
338f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
339a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
340f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
341a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
342a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
343a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
344f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
345a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
347f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
348f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
349f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
350f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
351f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
352f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
353f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
354f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
355f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
356f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
357f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
358f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
359f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
360f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
36113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3636c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3646c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3656c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3666c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3676c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
36813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
369b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
370b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
371b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3736c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3776b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3806b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
38113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
382b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
38313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3896b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3906b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3916b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3920e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3930e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
394b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
395b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
3960e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3970e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3983dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
399acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
400acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
401acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
402b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
403b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
404acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
405acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
406acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4073dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
41028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
41128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
41228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
41328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
41428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
415acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
416acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
417acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
419f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
420f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
421f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
422acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
423acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
424acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
425acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
428021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
429021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
430acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
431021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransformOrient =
432021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
436acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
43713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
438acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
4390f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        invTransform = (Transform(invTransformOrient) * Transform(invTransform))
4400f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos                .getOrientation();
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
442acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
443acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
446acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
447acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
448acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
449acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
450acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
451acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
452acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
453acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
454acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
455acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
456acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
457acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
458acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
465acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
469acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
47613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
47713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
47813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
47913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4809d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
4829d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
4839d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setGeometry(
4849d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const sp<const DisplayDevice>& hw,
4859d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer)
4869d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
487a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
4889d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
4919d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
4929d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setDefaultState();
4939d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
494a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4953e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5049d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setSkip(false);
5069d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
5079d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (isSecure() && !hw->isSecure()) {
5089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSkip(true);
5099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
5109d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
511dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5149d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5239d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5249d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!isOpaque(s) || s.alpha != 0xFF) {
5259d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setBlending(mPremultipliedAlpha ?
5269d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                HWC_BLENDING_PREMULT :
5279d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                HWC_BLENDING_COVERAGE);
5289d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
5299d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
53113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
53213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5336c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
534b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
535b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5363dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5379d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
538acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5399d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5409d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5419d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
542acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
543acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
54451450039e2fd266b31f33dfd1b4353bc1b0b145aPablo Ceballos        activeCrop = s.active.transform.inverse().transform(activeCrop, true);
54528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
54628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
54728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
54828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
54928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
55028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
551acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
552acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
553acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5606c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5616c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5626c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5633dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
564b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
565b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
566acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
567acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
568acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5699d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
570acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
571acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
572acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
576e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
577e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
578e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                mName.string(), transformedFrame.left, transformedFrame.top,
579e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                transformedFrame.right, transformedFrame.bottom,
580e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
581e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
582e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.displayFrame = transformedFrame;
583e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
5849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
587e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
588e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
589e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top,
590e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(),
591e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                static_cast<int32_t>(error));
592e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
593e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.sourceCrop = sourceCrop;
594e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
5979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
6069d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!frame.intersect(hw->getViewport(), &frame)) {
6079d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        frame.clear();
6089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
6099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr(hw->getTransform());
6109d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setFrame(tr.transform(frame));
6119d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setCrop(computeCrop(hw));
6129d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setPlaneAlpha(s.alpha);
6139d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
6149f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
61529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
61629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
61729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
61829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
61929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
62029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
62129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
62229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
62329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6243dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
625c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
626c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
627c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
628021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
629021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
630c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
631021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransform =
632021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
633c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
634c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
635c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
636c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
638c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6390f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        transform = Transform(invTransform) * transform;
640c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
64129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
64229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6449d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6559d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
6569d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (orientation & Transform::ROT_INVALID) {
6579d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // we can only handle simple transformation
6589d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSkip(true);
6599d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    } else {
6609d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setTransform(orientation);
6619d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
6629d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
663a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
664a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6659d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6749d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6769d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6990f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Sideband layers
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
7010f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Sideband);
7020f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Sideband composition", mName.string());
7030f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7090f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7120a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // Client layers
7130a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mHwcLayers[hwcId].forceClientComposition ||
7140a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
7150f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Client composition", mName.string());
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7170f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7180f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7190f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7200a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // SolidColor layers
7210a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mActiveBuffer == nullptr) {
7220a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        setCompositionType(hwcId, HWC2::Composition::SolidColor);
723c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
724c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // For now, we only support black for DimLayer
7250a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        error = hwcLayer->setColor({0, 0, 0, 255});
7260a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        if (error != HWC2::Error::None) {
7270a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
7280a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7290a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        }
730c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
731c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // Clear out the transform, because it doesn't make sense absent a
732c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // source buffer
733c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        error = hwcLayer->setTransform(HWC2::Transform::None);
734c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        if (error != HWC2::Error::None) {
735c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza            ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
736c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
737c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        }
738c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
7390a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        return;
7400a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    }
7410a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza
7420f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Device or Cursor layers
7430f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (mPotentialCursor) {
7440f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Cursor composition", mName.string());
7450f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Cursor);
7469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7500f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7510f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7520f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
7530f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (error != HWC2::Error::None) {
7540f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7550f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                mActiveBuffer->handle, to_string(error).c_str(),
7560f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                static_cast<int32_t>(error));
7570f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7599d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
7609d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
7619d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer) {
7629d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // we have to set the visible region on every frame because
7639d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // we currently free it during onLayerDisplayed(), which is called
7649d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // after HWComposer::commit() -- every frame.
7659d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // Apply this display's projection's viewport to the visible region
7669d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // before giving it to the HWC HAL.
7679d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr = hw->getTransform();
7689d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
7699d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setVisibleRegionScreen(visible);
7709d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setSurfaceDamage(surfaceDamageRegion);
7719d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
772ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
7739d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (mSidebandStream.get()) {
7749d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSidebandStream(mSidebandStream);
7759d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    } else {
7769d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // NOTE: buffer can be NULL if the client never drew into this
7779d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // layer yet, or if we ran out of memory
7789d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setBuffer(mActiveBuffer);
7799d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
7809d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
7819d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
7829d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
7839d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
7849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
7929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
793dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
7959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
7969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
797b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
798b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
8019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
802baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
8039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
804b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
805b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
806acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
8079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
8089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
8099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
8119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
8129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
8139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
8149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
8159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
8169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
8179d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
8189d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
8199d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer) {
8209d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    int fenceFd = -1;
8219d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8229d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // TODO: there is a possible optimization here: we only need to set the
8239d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // acquire fence the first time a new buffer is acquired on EACH display.
8249d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8259d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
8269d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8279d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        if (fence->isValid()) {
8289d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            fenceFd = fence->dup();
8299d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            if (fenceFd == -1) {
8309d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
8319d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            }
8329d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        }
8339d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8349d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setAcquireFenceFd(fenceFd);
8359d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
8369d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8379d96de49673cb6c916bfb797aad4f4e024ea73caFabien SanglardRect Layer::getPosition(
8389d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const sp<const DisplayDevice>& hw)
8399d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard{
8409d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // this gives us only the "orientation" component of the transform
8419d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const State& s(getCurrentState());
8429d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8439d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // apply the layer's transform, followed by the display's global transform
8449d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // here we're guaranteed that the layer's transform preserves rects
8459d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect win(s.active.w, s.active.h);
8469d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!s.crop.isEmpty()) {
8479d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        win.intersect(s.crop, &win);
8489d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8499d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // subtract the transparent region and snap to the bounds
8509d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect bounds = reduce(win, s.activeTransparentRegion);
8519d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect frame(s.active.transform.transform(bounds));
8529d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    frame.intersect(hw->getViewport(), &frame);
8539d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!s.finalCrop.isEmpty()) {
8549d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        frame.intersect(s.finalCrop, &frame);
8559d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8569d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr(hw->getTransform());
8579d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return Rect(tr.transform(frame));
8589d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
8599d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
86003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
866c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
869c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
870c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
871c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
874c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
875c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
876c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
877c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
878c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8811c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8821c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
883a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
885179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
886179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
887179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
888179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
889179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
890179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
891179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
892179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
893179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
894f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
895f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
896179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
897179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
900179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
9014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
902179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
903179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
904179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
905179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
9061b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
907179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
910a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
91197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
91297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
913bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
914bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
91597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
916dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
917dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
918dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
919dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
920dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
921dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
922875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
923875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
924dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
925cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
926eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
927cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
928cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
929cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
930bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
931bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
932cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
933c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
934c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
935c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
936021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the code below applies the primary display's inverse transform to
937021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the texture transform
938c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
939c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
940c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
941c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
942c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
943c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
944c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
945c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
946021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos            uint32_t transform =
947021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                    DisplayDevice::getPrimaryDisplayOrientationTransform();
948c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
949c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
950c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
951c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
952c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
953c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
954c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
955c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
956c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
957c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
958c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
959c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
960c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
961c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
962c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
963cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
96449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
96549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
96649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
96749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
96849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
969a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
970875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
971a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
972c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
973875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
977c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
978c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
979c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
98119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
982c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
98319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
98419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
992c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
993c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
9941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
996c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
1007c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
1012acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
1013acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1014b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1015acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
1016b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
1017acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1018acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1019acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
1020acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
1021acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1022acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1023acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1030875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1031875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1032ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1033ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1034ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1035ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1036ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1038875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10394125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10405cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1041875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10449d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
10459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1069ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
1070ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // If we're querying the composition type for a display that does not
1071ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // have a HWC counterpart, then it will always be Client
1072ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return HWC2::Composition::Client;
1073ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
1075ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        ALOGE("getCompositionType called with an invalid HWC layer");
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
10979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10981681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
10991681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
11001681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
11011681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
11021681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
11031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
11041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
11051681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
11061681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
11071681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
11081681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1109c5da271eec001da9e11a2786f2618a45257439c3Dan Stozabool Layer::latchUnsignaledBuffers() {
1110c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool propertyLoaded = false;
1111c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool latch = false;
1112c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static std::mutex mutex;
1113c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    std::lock_guard<std::mutex> lock(mutex);
1114c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (!propertyLoaded) {
1115c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        char value[PROPERTY_VALUE_MAX] = {};
1116c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        property_get("debug.sf.latch_unsignaled", value, "0");
1117c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        latch = atoi(value);
1118c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        propertyLoaded = true;
1119c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1120c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    return latch;
1121c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza}
1122c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
1123cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1124cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1125cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
11297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
11321ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stozabool Layer::headFenceHasSignaled() const {
11339d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1134c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (latchUnsignaledBuffers()) {
1135c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        return true;
1136c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1137c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
11381ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
11391ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems.empty()) {
11401ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11411ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11421ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems[0].mIsDroppable) {
11431ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // Even though this buffer's fence may not have signaled yet, it could
11441ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // be replaced by another buffer before it has a chance to, which means
11451ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // that it's possible to get into a situation where a buffer is never
11461ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // able to be latched. To avoid this, grab this buffer anyway.
11471ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11481ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11491ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
11509d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
11519d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return true;
11529d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
11531ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza}
11541ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1155cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1156cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1157cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1158cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1159cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1161cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1162cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1163cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1164cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1175ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1176ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1177ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1178ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1179ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1180ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1181ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11825773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1183a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1184a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1185ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11865773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11875773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11885773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1189dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11905773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11915773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1192dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1193ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1194ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1199acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1200acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1201acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1202acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1203acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1204acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1205acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1206acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1207acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1208acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1209acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1210acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1211acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1212acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1213acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1214c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1215c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
121613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
12171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1218acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
122013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1221b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1222b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
12246c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1225f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
12263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1227acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1228acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1229acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1230acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1231acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1232acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1233acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1234acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1235acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1236acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1237acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1238acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1239b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1240b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1241b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1242b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1243b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1244acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1245acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1246ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1247acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1248acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1249acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1250acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12525cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
125313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
125413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1255ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12564125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1257a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1258a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1259a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1260db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1261a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1262db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1263a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1264a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1265a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12664125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1267a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1268a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1269231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1270231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1271231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1272231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1273231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1274231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12757a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12767a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1277a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12787a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12797a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12807a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1281b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
128213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
1283c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
128413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
128513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
128613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
128713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
128813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
128913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
129013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
129113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
129213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
129313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
129413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
129513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
129613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
129713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
129813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
129913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
130013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
130113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
130213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
130413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
130513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
130613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
130713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
130813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
131013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
131113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
131213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
131313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
13157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
13167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
13177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
13207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
13217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
132222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<IBinder> strongBinder = mCurrentState.handle.promote();
132322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<Handle> handle = nullptr;
132422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<Layer> handleLayer = nullptr;
132522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        if (strongBinder != nullptr) {
132622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza            handle = static_cast<Handle*>(strongBinder.get());
132722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza            handleLayer = handle->owner.promote();
132822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        }
132922851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        if (strongBinder == nullptr || handleLayer == nullptr) {
13307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
13317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
13327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
13347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
13353bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
13363bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
13373bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1338cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1339cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1340cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1341cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1342cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1343cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1344cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
1349f5702ff8b1919e0a5d342ad04ac486bbcde41461Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
13507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
135405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::popPendingState(State* stateToCommit) {
135505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    auto oldFlags = stateToCommit->flags;
135605289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    *stateToCommit = mPendingStates[0];
135705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
135805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            (stateToCommit->flags & stateToCommit->mask);
13597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
136305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosbool Layer::applyPendingStates(State* stateToCommit) {
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
137205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1377cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1378cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1379cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1380cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1381cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1382cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1383cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1384cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1385cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1386cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1387cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
13887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
13897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
139005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
13947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
13957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1396792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1397792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
13987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
140005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            popPendingState(stateToCommit);
14017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
14027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
14067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
14077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
14087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
14097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
14107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
14137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
14147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1417cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
14181ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    bool headFenceSignaled = headFenceHasSignaled();
1419cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1420cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
14211ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
1422cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1423cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
14247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
142713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
14281c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
14291c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
14307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
143105289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    Layer::State c = getCurrentState();
143205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    if (!applyPendingStates(&c)) {
14337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
14347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
14391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1440a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1441a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1442cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14439d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1446b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1448b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
1449c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                this, getName().string(), mCurrentTransform,
1450c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getEffectiveScalingMode(),
14511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1452b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1453b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1454b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1455b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1456b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1457b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1460b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1461b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1462b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1463b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1464b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1465b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1466b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1467a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14682a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14692a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1470bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
147482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    const bool resizePending = (c.requested.w != c.active.w) ||
147582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            (c.requested.h != c.active.h);
14760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14779e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
147813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
14790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
14800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
14810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
14820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
14830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
14840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
14850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
14869e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
14879e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
14889e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
14899e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
14900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
14920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
14930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
14940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
149513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
149613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
149713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
149813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
14997d05257585918bd578bc0bc18f32571a48a7304aPablo Ceballos        Layer::State& editCurrentState(getCurrentState());
150082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        if (mFreezePositionUpdates) {
150182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float tx = c.active.transform.tx();
150282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float ty = c.active.transform.ty();
150382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
150482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active.transform.set(tx, ty);
150582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = c.active;
150682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        } else {
150782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = editCurrentState.requested;
150882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
150982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        }
151013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
151113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
151413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
152013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
152113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
152213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
15233dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
15243dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
152513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
152613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
152713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1528c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // If the layer is hidden, signal and clear out all local sync points so
1529c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // that transactions for layers depending on this layer's frames becoming
1530c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // visible are not blocked
1531c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    if (c.flags & layer_state_t::eLayerHidden) {
1532c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        Mutex::Autolock lock(mLocalSyncPointMutex);
1533c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        for (auto& point : mLocalSyncPoints) {
1534c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza            point->setFrameAvailable();
1535c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        }
1536c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        mLocalSyncPoints.clear();
1537c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
1538c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza
153913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
154005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    commitTransaction(c);
154113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::commitTransaction(const State& stateToCommit) {
154505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    mDrawingState = stateToCommit;
1546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
154813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
154913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
155013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
155213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
155313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
155413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
155682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carrbool Layer::setPosition(float x, float y, bool immediate) {
15573dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
155813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
155913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
156069663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
156169663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
156269663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
156369663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15643dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
156582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    if (immediate && !mFreezePositionUpdates) {
156682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mCurrentState.active.transform.set(x, y);
156782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    }
156882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    mFreezePositionUpdates = mFreezePositionUpdates || !immediate;
156969663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
157113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
157213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
157313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
157482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr
157513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
157613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
157713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
157813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
157913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
158113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
158213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
158313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
158413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
158513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
158613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
158713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
158813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
15897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
159013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
159113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
159213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15939d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
15949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
15959d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
15969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardbool Layer::setAlpha(uint8_t alpha) {
15979d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
159813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
159913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
160013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
160113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
16027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
160313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
160413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
160513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
160613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
160713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
16083dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
160913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
16107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
161113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
161213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
161313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
161413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
16152ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
16167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
161713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
161813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
161913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
162013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
162113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
162213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
162313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
162413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
162513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
16267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
16277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
162813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
163013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
163199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
163299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carrbool Layer::setCrop(const Rect& crop, bool immediate) {
1633b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
163413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
163699e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    mCurrentState.requestedCrop = crop;
163799e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    if (immediate) {
163899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        mCurrentState.crop = crop;
163999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    }
16407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
164113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
164313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1644acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1645b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1646acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1647acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1648b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1649acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1650acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1651acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1652acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
165313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1654c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carrbool Layer::setOverrideScalingMode(int32_t scalingMode) {
1655c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (scalingMode == mOverrideScalingMode)
1656c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        return false;
1657c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    mOverrideScalingMode = scalingMode;
165882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    setTransactionFlags(eTransactionNeeded);
1659c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return true;
1660c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1661c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
1662c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carruint32_t Layer::getEffectiveScalingMode() const {
1663c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (mOverrideScalingMode >= 0) {
1664c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr      return mOverrideScalingMode;
1665c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    }
1666c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return mCurrentScalingMode;
1667c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1668c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
166913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
167013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
167113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
167213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
167313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
16747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
167513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
167613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1677a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1678a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
16797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
16807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
16817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
16827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
16837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
16847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
16857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
16867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1687792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1688792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
16897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
16907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
16917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1692ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1693ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1694ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1695ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1696ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1697ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1698ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1699ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1700ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1701ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1702ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1703ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17086b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1709ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1710d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1711d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1712d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
17136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
17140eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
17150eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
17160eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
17170eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
17186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
17196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
17200eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17210eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
17220eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
17230eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
17240eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
17250eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
17260eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17270eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
17280eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
17296b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
17306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
17314d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
17324d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1733ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
173499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
173599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1736e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozabool Layer::onPostComposition() {
1737e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    bool frameLatencyNeeded = mFrameLatencyNeeded;
1738d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1739bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
174082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
174182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1742bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1743789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
174482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
174582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
174682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
174782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
174882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
174982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
175082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1751d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
17529d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
17539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
17549d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
17559d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
17569d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1757789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
175882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
175982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
176082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
176182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
176282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
176382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
176482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
176582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
176682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1767d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1768d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1769e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return frameLatencyNeeded;
1770d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1771d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
17729d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
17739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
17749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
17759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
17769d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
17779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1778da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
177913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
17809d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
17819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
17829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17839d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
17849d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
17859d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17869d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1787da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1788da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
17894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17911c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
17921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1793399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1794399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1795399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
179612e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
179712e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
179812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
179912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
18005bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
18015bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
18025bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
18033dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1804399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1805399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
18064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1807223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mQueuedFrames <= 0 && !mAutoRefresh) {
1808223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1809223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
181099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1811223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // if we've already called updateTexImage() without going through
1812223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // a composition step, we have to skip this layer at this point
1813223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // because we cannot call updateTeximage() without a corresponding
1814223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // compositionComplete() call.
1815223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // we'll trigger an update in onPreComposition().
1816223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mRefreshPending) {
1817223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1818223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
18191ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1820223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // If the head buffer's acquire fence hasn't signaled yet, return and
1821223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // try again later
1822223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (!headFenceHasSignaled()) {
1823223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1824223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1825223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
18262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1827223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Capture the old state of the layer for comparisons later
1828223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const State& s(getDrawingState());
1829223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const bool oldOpacity = isOpaque(s);
1830223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1831223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1832223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
1833223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Layer::State& front;
1834223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Layer::State& current;
1835223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        bool& recomputeVisibleRegions;
1836223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        bool stickyTransformSet;
1837223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        const char* name;
1838223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        int32_t overrideScalingMode;
1839223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        bool& freezePositionUpdates;
1840223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1841223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Reject(Layer::State& front, Layer::State& current,
1842223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                bool& recomputeVisibleRegions, bool stickySet,
1843223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                const char* name,
1844223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                int32_t overrideScalingMode,
1845223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                bool& freezePositionUpdates)
1846223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            : front(front), current(current),
1847223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard              recomputeVisibleRegions(recomputeVisibleRegions),
1848223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard              stickyTransformSet(stickySet),
1849223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard              name(name),
1850223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard              overrideScalingMode(overrideScalingMode),
1851223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard              freezePositionUpdates(freezePositionUpdates) {
1852223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
18532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1854223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        virtual bool reject(const sp<GraphicBuffer>& buf,
1855223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                const BufferItem& item) {
1856223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (buf == NULL) {
1857223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                return false;
1858223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
18592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1860223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            uint32_t bufWidth  = buf->getWidth();
1861223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            uint32_t bufHeight = buf->getHeight();
18622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1863223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // check that we received a buffer of the right size
1864223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // (Take the buffer's orientation into account)
1865223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (item.mTransform & Transform::ROT_90) {
1866223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                swap(bufWidth, bufHeight);
1867223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
18682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1869223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            int actualScalingMode = overrideScalingMode >= 0 ?
1870223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    overrideScalingMode : item.mScalingMode;
1871223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1872223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (front.active != front.requested) {
18732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
1874223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                if (isFixedSize ||
1875223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        (bufWidth == front.requested.w &&
1876223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                         bufHeight == front.requested.h))
1877223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                {
1878223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    // Here we pretend the transaction happened by updating the
1879223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    // current and drawing states. Drawing state is only accessed
1880223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    // in this thread, no need to have it locked
1881223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    front.active = front.requested;
18826c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18836c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
18846c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
18856c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
18866c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
18876c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
18886c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
1889223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    current.active = front.active;
1890223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    current.modified = true;
18916c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18926c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
18932ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
18942ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
18952ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
1896223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                ALOGD_IF(DEBUG_RESIZE,
1897223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
1898223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1899223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        "            requested={ wh={%4u,%4u} }}\n",
1900223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        name,
1901223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        bufWidth, bufHeight, item.mTransform, item.mScalingMode,
1902223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.active.w, front.active.h,
1903223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.left,
1904223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.top,
1905223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.right,
1906223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.bottom,
1907223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.getWidth(),
1908223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.crop.getHeight(),
1909223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                        front.requested.w, front.requested.h);
1910223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
191199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
1912223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (!isFixedSize && !stickyTransformSet) {
1913223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                if (front.active.w != bufWidth ||
1914223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    front.active.h != bufHeight) {
1915223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    // reject this buffer
1916223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    ALOGE("[%s] rejecting buffer: "
1917223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                            "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1918223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                            name, bufWidth, bufHeight, front.active.w, front.active.h);
1919223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    return true;
1920223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                }
19212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
19222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1923223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // if the transparent region has changed (this test is
1924223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // conservative, but that's fine, worst case we're doing
1925223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // a bit of extra work), we latch the new one and we
1926223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            // trigger a visible-region recompute.
1927223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (!front.activeTransparentRegion.isTriviallyEqual(
1928223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    front.requestedTransparentRegion)) {
1929223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                front.activeTransparentRegion = front.requestedTransparentRegion;
1930223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1931223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // We also need to update the current state so that
1932223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // we don't end-up overwriting the drawing state with
1933223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // this stale current state during the next transaction
1934223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                //
1935223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // NOTE: We don't need to hold the transaction lock here
1936223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // because State::active is only accessed from this thread.
1937223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                current.activeTransparentRegion = front.activeTransparentRegion;
1938223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1939223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // recompute visible region
1940223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                recomputeVisibleRegions = true;
1941223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
19422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1943223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (front.crop != front.requestedCrop) {
1944223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                front.crop = front.requestedCrop;
1945223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                current.crop = front.requestedCrop;
1946223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                recomputeVisibleRegions = true;
1947223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
1948223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            freezePositionUpdates = false;
19497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1950223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            return false;
1951223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
1952223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    };
1953cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1954223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1955223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            getProducerStickyTransform() != 0, mName.string(),
1956223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mOverrideScalingMode, mFreezePositionUpdates);
1957cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1958cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1959223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Check all of our local sync points to ensure that all transactions
1960223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // which need to have been applied prior to the frame which is about to
1961223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // be latched have signaled
1962cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1963223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    auto headFrameNumber = getHeadFrameNumber();
1964223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    bool matchingFramesFound = false;
1965223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    bool allTransactionsApplied = true;
1966223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    {
1967223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Mutex::Autolock lock(mLocalSyncPointMutex);
1968223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        for (auto& point : mLocalSyncPoints) {
1969223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (point->getFrameNumber() > headFrameNumber) {
1970223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                break;
19717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1972a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1973223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            matchingFramesFound = true;
1974cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1975223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (!point->frameIsAvailable()) {
1976223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // We haven't notified the remote layer that the frame for
1977223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // this point is available yet. Notify it now, and then
1978223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // abort this attempt to latch.
1979223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                point->setFrameAvailable();
1980223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                allTransactionsApplied = false;
1981223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                break;
198265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
198365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
1984223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            allTransactionsApplied &= point->transactionIsApplied();
19851585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
1986223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
19871585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1988223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (matchingFramesFound && !allTransactionsApplied) {
1989223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1990223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1991223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1992223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1993223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // This boolean is used to make sure that SurfaceFlinger's shadow copy
1994223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // of the buffer queue isn't modified when the buffer queue is returning
1995223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // BufferItem's that weren't actually queued. This can happen in shared
1996223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // buffer mode.
1997223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    bool queuedBuffer = false;
1998223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1999223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
2000223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mLastFrameNumberReceived);
2001223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (updateResult == BufferQueue::PRESENT_LATER) {
2002223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Producer doesn't want buffer to be displayed yet.  Signal a
2003223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // layer update so we check again at the next opportunity.
2004223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
2005223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
2006223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
2007223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // If the buffer has been rejected, remove it from the shadow queue
2008223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // and return early
2009063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
20106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
2011223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mQueueItems.removeAt(0);
2012223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_dec(&mQueuedFrames);
2013223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
2014223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
2015223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
2016223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // This can occur if something goes wrong when trying to create the
2017223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // EGLImage for this buffer. If this happens, the buffer has already
2018223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // been released, so we need to clean up the queue and bug out
2019223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // early.
2020223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        if (queuedBuffer) {
2021223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            Mutex::Autolock lock(mQueueItemLock);
2022223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mQueueItems.clear();
2023223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_and(0, &mQueuedFrames);
2024223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
2025ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
2026223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Once we have hit this state, the shadow queue may no longer
2027223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // correctly reflect the incoming BufferQueue's contents, so even if
2028223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // updateTexImage starts working, the only safe course of action is
2029223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // to continue to ignore updates.
2030223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mUpdateTexImageFailed = true;
2031ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
2032223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
2033223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2034223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2035223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (queuedBuffer) {
2036223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Autolock scope
2037223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2038223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2039223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Mutex::Autolock lock(mQueueItemLock);
2040223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2041223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Remove any stale buffers that have been dropped during
2042223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // updateTexImage
2043223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
20446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
2045223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_dec(&mQueuedFrames);
20466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
20476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
2048223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mQueueItems.removeAt(0);
2049223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2050ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20511585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
2052223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Decrement the queued-frames count.  Signal another event if we
2053223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // have more frames pending.
2054223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
2055223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            || mAutoRefresh) {
2056223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
2057223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2058d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
2059223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (updateResult != NO_ERROR) {
2060223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // something happened!
2061223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2062223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
2063223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2064da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
2065223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // update the active buffer
2066223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
2067223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mActiveBuffer == NULL) {
2068223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // this can only happen if the very first buffer was rejected.
2069223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
2070223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2071702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2072223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mRefreshPending = true;
2073223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mFrameLatencyNeeded = true;
2074223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldActiveBuffer == NULL) {
2075223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard         // the first time we receive a buffer, we need to trigger a
2076223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard         // geometry invalidation.
2077223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2078223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard     }
2079223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2080223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
2081223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
2082223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
2083223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if ((crop != mCurrentCrop) ||
2084223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        (transform != mCurrentTransform) ||
2085223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        (scalingMode != mCurrentScalingMode))
2086223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    {
2087223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentCrop = crop;
2088223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentTransform = transform;
2089223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentScalingMode = scalingMode;
2090223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2091223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2092702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2093223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldActiveBuffer != NULL) {
2094223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        uint32_t bufWidth  = mActiveBuffer->getWidth();
2095223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        uint32_t bufHeight = mActiveBuffer->getHeight();
2096223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        if (bufWidth != uint32_t(oldActiveBuffer->width) ||
2097223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            bufHeight != uint32_t(oldActiveBuffer->height)) {
2098702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
2099702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2100223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2101702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2102223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
2103223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldOpacity != isOpaque(s)) {
2104223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2105223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2106cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2107223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2108223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2109223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Remove any sync points corresponding to the buffer which was just
2110223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // latched
2111223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    {
2112223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Mutex::Autolock lock(mLocalSyncPointMutex);
2113223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        auto point = mLocalSyncPoints.begin();
2114223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        while (point != mLocalSyncPoints.end()) {
2115223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (!(*point)->frameIsAvailable() ||
2116223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    !(*point)->transactionIsApplied()) {
2117223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // This sync point must have been added since we started
2118223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // latching. Don't drop it yet.
2119223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                ++point;
2120223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                continue;
2121223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
2122223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2123223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2124223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                point = mLocalSyncPoints.erase(point);
2125223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            } else {
2126223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                ++point;
2127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2129223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2131223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // FIXME: postedRegion should be dirty & bounds
2132223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    Region dirtyRegion(Rect(s.active.w, s.active.h));
2133223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2134223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // transform the dirty region to window-manager space
2135223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    outDirtyRegion = (s.active.transform.transform(dirtyRegion));
21361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
21374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
214113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
214213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
214313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
214413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
214513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
214613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
214703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
214803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
214903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
215013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
215113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
215213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
215313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
215413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
215513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
215613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
215713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
215813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
215913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
216013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
216113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
216213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
216313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
216413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
216513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
216613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
216713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
216813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
216913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
217013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
217113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
217213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
21741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
21751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
217613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
217874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
217913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
218013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
21813e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
218213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21832ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
218413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2185ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
218613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
218713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
218874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2189acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2190acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
219113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
21929d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
21939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21949d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
21959d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
219713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
21983dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2199b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2200b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2201b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2202b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
22034125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
220413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
22053dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
22063dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
220713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
22081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2209a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2210a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
22111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
22121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
22131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
22141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2215a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
22161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
221774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
22181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2219ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
22206905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2221a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
22226905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
22231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2224bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
22253d1d280fa3cbc30700f728a4b13e5308315433d3Colin Cross        mSurfaceFlingerConsumer->dumpState(result, "            ");
2226bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2227d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2228d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
22299d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
2230e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDumpHeader(String8& result) {
2231e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2232e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2233e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Layer name\n");
2234e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("           Z | ");
2235e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Comp Type | ");
2236e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("  Disp Frame (LTRB) | ");
2237e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("         Source Crop (LTRB)\n");
2238e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2239e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2240e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
2241e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2242e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDump(String8& result, int32_t hwcId) const {
2243e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
2244e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        return;
2245e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2246e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2247e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    String8 name;
2248e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mName.length() > 77) {
2249e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        std::string shortened;
2250e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string(), 36);
2251e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append("[...]");
2252e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string() + (mName.length() - 36), 36);
2253e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = shortened.c_str();
2254e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
2255e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = mName;
2256e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2257e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2258e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat(" %s\n", name.string());
2259e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2260e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Layer::State& layerState(getDrawingState());
2261e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
2262e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("  %10u | ", layerState.z);
2263e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%10s | ",
2264e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            to_string(getCompositionType(hwcId)).c_str());
2265e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Rect& frame = hwcInfo.displayFrame;
2266e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top,
2267e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            frame.right, frame.bottom);
2268e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const FloatRect& crop = hwcInfo.sourceCrop;
2269e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top,
2270e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            crop.right, crop.bottom);
2271e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2272e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - - ");
2273e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - -\n");
2274e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
22759d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
2276e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2277d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2278d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
227982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
228082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2281d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2282d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
228325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
228425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
22856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
22866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
22876547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
22886547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2289d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2290d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2291d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2292d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
229340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
229440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        bool* outIsGlesComposition, nsecs_t* outPostedTime,
229540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
229640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outName = mName;
229740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
229840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
22999d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
230040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
230140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
230240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            HWC2::Composition::Client : true;
23039d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
23049d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    *outIsGlesComposition = mIsGlesComposition;
23059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
230640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
230740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
230840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
230940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
2310e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2311e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastd::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
2312e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool forceFlush) {
2313e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::vector<OccupancyTracker::Segment> history;
2314e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush,
2315e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            &history);
2316e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    if (result != NO_ERROR) {
2317e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(),
2318e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                result);
2319e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        return {};
2320e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2321e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return history;
2322e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2323e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2324367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carrbool Layer::getTransformToDisplayInverse() const {
2325367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
2326367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr}
2327367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr
232813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
232913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
23303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
23333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
23343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
23373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
23383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2339