Layer.cpp revision 3890c3995c4a52439844faeb80b5503d42b977d8
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"
477b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard#include "LayerRejecter.h"
48b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
511b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
521b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
53875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
54875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
55c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza#include <mutex>
56c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
7113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
7213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
7313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
7413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStateMutex(),
767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStates(),
77a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
78399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
79a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
80933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
81c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        mOverrideScalingMode(-1),
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
83d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mBufferLatched(false),
84cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
85d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mPreviousFrameNumber(-1U),
864d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
8782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
8813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
905cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
919d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifndef USE_HWC2
929d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        mIsGlesComposition(false),
939d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
9413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
9513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
9603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
97a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
98a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
99a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
100a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
10165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
10204839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
10382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mAutoRefresh(false),
10482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mFreezePositionUpdates(false)
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1069d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
110a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
11249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1164125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1174125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1184125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
119231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
120231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1293dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.active.transform.set(0, 0);
130b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop.makeInvalid();
131b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop.makeInvalid();
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1339d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1359d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
1369d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    mCurrentState.alpha = 0xFF;
1379d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1469d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1509d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
1519d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    nsecs_t displayPeriod =
1529d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1539d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1546547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
155e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
156e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
159b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
160b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
161468051e20be19130572231266db306396a56402bIrvel    BufferQueue::createBufferQueue(&producer, &consumer, nullptr, true);
162b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
163468051e20be19130572231266db306396a56402bIrvel    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
164bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
165399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
167b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
168c9d972065c44860306add0172b5185bd8611f9eeDan Stoza#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
16919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
170303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1716905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
174b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17596f0819f81293076e652792794a961543e6750d7Mathias Agopian
1764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1778ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1788ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1798ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1808ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1818ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
182cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
183cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
184cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
185c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    for (auto& point : mLocalSyncPoints) {
186c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        point->setFrameAvailable();
187c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
188921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
19096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
19196f0819f81293076e652792794a961543e6750d7Mathias Agopian
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
2009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
2019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
2029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
2039d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
2049d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
2059d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface* layer) {
2069d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (layer) {
2079d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer->onDisplayed();
2089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
2099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
2109d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
2119d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
217468051e20be19130572231266db306396a56402bIrvel        mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
218468051e20be19130572231266db306396a56402bIrvel                item.mGraphicBuffer->getHeight(), item.mFrameNumber);
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
225a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
226a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
231a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
232a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
233a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
235ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
236a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
237a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
238a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
239a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
243579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
244579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2456b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
248a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
256a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
257a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2624d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
2637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
270399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
271399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
272399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
273399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
274399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
275399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
276399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2776710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2786710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
281bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
28248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
283cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
327582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
328582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
329b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
330b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
33513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
337a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
338a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
339a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
340f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
341f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
342a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
343f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
344a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
345a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
346a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
347f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
348a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
350f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
351f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
352f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
353f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
354f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
355f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
356f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
357f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
358f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
359f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
360f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
361f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
362f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
363f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
36413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3666c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3676c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3686c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3696c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3706c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
372b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
373b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
374b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3766c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3776c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3806b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
38113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
38213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3836b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
38413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
385b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3916b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3926b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3936b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3946b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3950e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3960e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
397b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
398b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
3990e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
4000e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4013dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
402acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
403acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
404acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
405b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
406b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
407acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
408acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
409acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4103dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
41113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
41228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
41328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
41428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
41528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
41628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
41728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
418acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
419acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
420acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
42113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
422f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
423f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
424f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
425acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
428acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
429acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
430acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
431021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
432021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
434021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransformOrient =
435021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
436acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
437acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
438acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
439acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
44013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
4420f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        invTransform = (Transform(invTransformOrient) * Transform(invTransform))
4430f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos                .getOrientation();
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
446acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
447acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
448acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
449acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
450acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
451acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
452acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
453acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
454acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
455acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
456acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
457acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
458acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
462acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
466acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
46913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
476acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
477acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
478acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
47913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
48013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
48113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
48213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4839d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
4849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
4859d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
4869d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setGeometry(
4879d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const sp<const DisplayDevice>& hw,
4889d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer)
4899d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
490a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
4919d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
4939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
4949d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
4959d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setDefaultState();
4969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
497a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4983e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4999d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5079d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setSkip(false);
5099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
5109d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (isSecure() && !hw->isSecure()) {
5119d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSkip(true);
5129d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
5139d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
514dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5179d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5269d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5279d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!isOpaque(s) || s.alpha != 0xFF) {
5289d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setBlending(mPremultipliedAlpha ?
5299d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                HWC_BLENDING_PREMULT :
5309d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                HWC_BLENDING_COVERAGE);
5319d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
5329d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
53313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
53413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
53513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
537b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
538b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5393dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5409d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
541acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5429d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
5439d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5449d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
545acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
546acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
54751450039e2fd266b31f33dfd1b4353bc1b0b145aPablo Ceballos        activeCrop = s.active.transform.inverse().transform(activeCrop, true);
54828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
54928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
55028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
55128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
55228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
55328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
554acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
555acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
556acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5606c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5616c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5626c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5636c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5646c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5656c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5663dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
567b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
568b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
569acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
570acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
571acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5729d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
573acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
574acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
575acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
579e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
580e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
581e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                mName.string(), transformedFrame.left, transformedFrame.top,
582e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                transformedFrame.right, transformedFrame.bottom,
583e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
584e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
585e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.displayFrame = transformedFrame;
586e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
590e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (error != HWC2::Error::None) {
591e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
592e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top,
593e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(),
594e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza                static_cast<int32_t>(error));
595e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
596e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        hwcInfo.sourceCrop = sourceCrop;
597e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
6059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
6069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
6079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
6099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!frame.intersect(hw->getViewport(), &frame)) {
6109d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        frame.clear();
6119d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
6129d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr(hw->getTransform());
6139d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setFrame(tr.transform(frame));
6149d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setCrop(computeCrop(hw));
6159d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setPlaneAlpha(s.alpha);
6169d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
6179f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
61829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
61929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
62029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
62129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
62229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
62329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
62429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
62529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
62629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6273dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
628c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
629c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
630c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
631021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
632021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
633c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
634021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransform =
635021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
636c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
638c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
639c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
640c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
641c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6420f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        transform = Transform(invTransform) * transform;
643c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
64429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
64529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
64613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6479d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6589d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
6599d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (orientation & Transform::ROT_INVALID) {
6609d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // we can only handle simple transformation
6619d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSkip(true);
6629d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    } else {
6639d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setTransform(orientation);
6649d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
6659d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
666a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
667a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6689d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6779d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6799d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7020f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Sideband layers
7039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
7040f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Sideband);
7050f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Sideband composition", mName.string());
7060f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7120f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7150a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // Client layers
7160a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mHwcLayers[hwcId].forceClientComposition ||
7170a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
7180f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Client composition", mName.string());
7199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7200f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7210f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7220f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7230a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    // SolidColor layers
7240a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    if (mActiveBuffer == nullptr) {
7250a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        setCompositionType(hwcId, HWC2::Composition::SolidColor);
726c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
727c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // For now, we only support black for DimLayer
7280a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        error = hwcLayer->setColor({0, 0, 0, 255});
7290a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        if (error != HWC2::Error::None) {
7300a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza            ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
7310a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7320a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        }
733c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
734c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // Clear out the transform, because it doesn't make sense absent a
735c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        // source buffer
736c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        error = hwcLayer->setTransform(HWC2::Transform::None);
737c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        if (error != HWC2::Error::None) {
738c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza            ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
739c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
740c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza        }
741c6c8954b4258ed61790dcc95ff1d049be3e8422dDan Stoza
7420a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza        return;
7430a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza    }
7440a21df783892acc5cff0c39c79b0aa602074af7eDan Stoza
7450f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Device or Cursor layers
7460f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (mPotentialCursor) {
7470f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Cursor composition", mName.string());
7480f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Cursor);
7499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7530f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7540f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7550f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
7560f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (error != HWC2::Error::None) {
7570f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7580f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                mActiveBuffer->handle, to_string(error).c_str(),
7590f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                static_cast<int32_t>(error));
7600f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7629d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
7639d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
7649d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer) {
7659d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // we have to set the visible region on every frame because
7669d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // we currently free it during onLayerDisplayed(), which is called
7679d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // after HWComposer::commit() -- every frame.
7689d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // Apply this display's projection's viewport to the visible region
7699d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // before giving it to the HWC HAL.
7709d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr = hw->getTransform();
7719d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
7729d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setVisibleRegionScreen(visible);
7739d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setSurfaceDamage(surfaceDamageRegion);
7749d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
775ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
7769d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (mSidebandStream.get()) {
7779d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setSidebandStream(mSidebandStream);
7789d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    } else {
7799d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // NOTE: buffer can be NULL if the client never drew into this
7809d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        // layer yet, or if we ran out of memory
7819d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        layer.setBuffer(mActiveBuffer);
7829d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
7839d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
7849d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
7859d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
7869d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
7879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
7959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
796dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
7979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
7989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
800b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
801b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
8029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
8049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
805baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
8069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
807b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
808b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
809acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
8109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
8119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
8129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
8149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
8159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
8169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
8179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
8189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
8199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
8209d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
8219d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardvoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
8229d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        HWComposer::HWCLayerInterface& layer) {
8239d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    int fenceFd = -1;
8249d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8259d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // TODO: there is a possible optimization here: we only need to set the
8269d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // acquire fence the first time a new buffer is acquired on EACH display.
8279d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8289d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
8299d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8309d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        if (fence->isValid()) {
8319d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            fenceFd = fence->dup();
8329d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            if (fenceFd == -1) {
8339d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
8349d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            }
8359d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        }
8369d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8379d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    layer.setAcquireFenceFd(fenceFd);
8389d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
8399d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8409d96de49673cb6c916bfb797aad4f4e024ea73caFabien SanglardRect Layer::getPosition(
8419d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const sp<const DisplayDevice>& hw)
8429d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard{
8439d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // this gives us only the "orientation" component of the transform
8449d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const State& s(getCurrentState());
8459d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard
8469d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // apply the layer's transform, followed by the display's global transform
8479d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // here we're guaranteed that the layer's transform preserves rects
8489d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect win(s.active.w, s.active.h);
8499d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!s.crop.isEmpty()) {
8509d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        win.intersect(s.crop, &win);
8519d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8529d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    // subtract the transparent region and snap to the bounds
8539d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect bounds = reduce(win, s.activeTransparentRegion);
8549d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    Rect frame(s.active.transform.transform(bounds));
8559d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    frame.intersect(hw->getViewport(), &frame);
8569d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    if (!s.finalCrop.isEmpty()) {
8579d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard        frame.intersect(s.finalCrop, &frame);
8589d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    }
8599d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    const Transform& tr(hw->getTransform());
8609d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return Rect(tr.transform(frame));
8619d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard}
8629d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
86303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
86413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
869c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
872c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
873c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
874c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
877c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
878c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
880c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
881c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
882c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
886a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
888179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
889179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
890179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
891179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
892179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
893179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
894179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
895179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
896179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
897f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
898f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
899179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
900179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
903179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
9044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
905179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
906179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
907179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
908179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
9091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
910179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
913a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
91497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
91597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
916bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
917bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
91897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
919dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
920dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
921dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
922dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
923dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
924dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
925875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
926875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
927dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
928cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
929eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
930cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
931cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
932cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
933bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
934bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
935cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
936c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
937c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
938c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
939021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the code below applies the primary display's inverse transform to
940021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the texture transform
941c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
942c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
943c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
944c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
945c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
946c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
947c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
948c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
949021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos            uint32_t transform =
950021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                    DisplayDevice::getPrimaryDisplayOrientationTransform();
951c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
952c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
953c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
954c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
955c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
956c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
957c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
958c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
959c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
960c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
961c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
962c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
963c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
964c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
965c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
966cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
96749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
96849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
96949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
97049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
97149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
972a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
973875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
974a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
975c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
976875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
980c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
981c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
982c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
98419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
985c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
98619733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
98719733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
995c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
996c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
9971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
999c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
1010c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
1015acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
1016acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1017b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1018acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
1019b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
1020acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1021acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1022acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
1023acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
1024acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1025acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1026acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1033875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1034875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1035ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1036ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1037ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1038ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1039ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
104013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1041875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10424125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10435cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1044875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
104513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10479d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1072ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
1073ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // If we're querying the composition type for a display that does not
1074ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // have a HWC counterpart, then it will always be Client
1075ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return HWC2::Composition::Client;
1076ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
1078ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        ALOGE("getCompositionType called with an invalid HWC layer");
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
10989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10999d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
11009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11011681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
11021681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
11031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
11041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
11051681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
11061681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
11071681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
11081681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
11091681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
11101681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
11111681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1112c5da271eec001da9e11a2786f2618a45257439c3Dan Stozabool Layer::latchUnsignaledBuffers() {
1113c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool propertyLoaded = false;
1114c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool latch = false;
1115c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static std::mutex mutex;
1116c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    std::lock_guard<std::mutex> lock(mutex);
1117c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (!propertyLoaded) {
1118c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        char value[PROPERTY_VALUE_MAX] = {};
1119c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        property_get("debug.sf.latch_unsignaled", value, "0");
1120c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        latch = atoi(value);
1121c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        propertyLoaded = true;
1122c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1123c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    return latch;
1124c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza}
1125c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
1126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1129cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1131cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
11327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1133cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
11351ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stozabool Layer::headFenceHasSignaled() const {
11369d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
1137c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (latchUnsignaledBuffers()) {
1138c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        return true;
1139c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1140c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
11411ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
11421ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems.empty()) {
11431ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11441ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11451ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems[0].mIsDroppable) {
11461ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // Even though this buffer's fence may not have signaled yet, it could
11471ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // be replaced by another buffer before it has a chance to, which means
11481ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // that it's possible to get into a situation where a buffer is never
11491ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // able to be latched. To avoid this, grab this buffer anyway.
11501ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11511ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11521ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
11539d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
11549d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return true;
11559d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
11561ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza}
11571ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1158cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1159cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1160cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1161cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1162cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1164cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1165cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1166cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1167cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1178ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1179ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1180ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1181ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1182ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1183ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1184ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11855773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1186a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1187a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1188ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11895773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11905773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11915773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1192dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11935773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11945773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1195dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1196ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1197ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
120013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
120113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1202acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1203acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1204acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1205acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1206acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1207acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1208acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1209acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1210acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1211acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1212acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1213acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1214acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1215acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1216acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1217c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1218c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
121913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
12201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1221acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1224b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1225b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
122613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
12276c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1228f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
12293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1230acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1231acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1232acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1233acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1234acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1235acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1236acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1237acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1238acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1239acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1240acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1241acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1242b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1243b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1244b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1245b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1246b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1247acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1248acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1249ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1250acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1251acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1252acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1253acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12555cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
125613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
125713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1258ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12594125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1260a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1261a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1262a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1263db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1264a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1265db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1266a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1267a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1268a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12694125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1270a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1271a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1272231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1273231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1274231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1275231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1276231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1277231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12787a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12797a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1280a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12817a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12827a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12837a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1284b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
128513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
1286c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
128713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
128813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
128913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
129013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
129113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
129213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
129313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
129413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
129513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
129613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
129713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
129813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
129913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
130013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
130213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
130313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
130413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
130513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
130613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
130713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
130813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
130913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
131013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
131113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
131213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
131313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
131413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
131613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
13187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
13197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
13207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
13237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
13247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
132522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<IBinder> strongBinder = mCurrentState.handle.promote();
132622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<Handle> handle = nullptr;
132722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        sp<Layer> handleLayer = nullptr;
132822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        if (strongBinder != nullptr) {
132922851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza            handle = static_cast<Handle*>(strongBinder.get());
133022851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza            handleLayer = handle->owner.promote();
133122851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        }
133222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        if (strongBinder == nullptr || handleLayer == nullptr) {
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
13347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
13357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
13367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
13377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
13383bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
13393bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
13403bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1341cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1342cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1343cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1344cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1345cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1346cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1347cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
1352f5702ff8b1919e0a5d342ad04ac486bbcde41461Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
13537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
135705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::popPendingState(State* stateToCommit) {
135805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    auto oldFlags = stateToCommit->flags;
135905289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    *stateToCommit = mPendingStates[0];
136005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
136105289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            (stateToCommit->flags & stateToCommit->mask);
13627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
136605289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosbool Layer::applyPendingStates(State* stateToCommit) {
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
137505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1380cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1381cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1382cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1383cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1384cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1385cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1386cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1387cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1388cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1389cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1390cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
13917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
13927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
139305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
13977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
13987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1399792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1400792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
14017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
14027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
140305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            popPendingState(stateToCommit);
14047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
14057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
14067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
14097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
14107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
14117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
14127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
14137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
14167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
14177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1420cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
14211ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    bool headFenceSignaled = headFenceHasSignaled();
1422cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1423cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
14241ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
1425cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1426cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
14277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
14297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
143013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
14311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
14321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
14337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
143405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    Layer::State c = getCurrentState();
143505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    if (!applyPendingStates(&c)) {
14367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
14377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
14391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
14421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1443a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1444a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14469d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14476905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1449b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1451b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
1452c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                this, getName().string(), mCurrentTransform,
1453c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getEffectiveScalingMode(),
14541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1455b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1456b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1457b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1458b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1459b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1460b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1463b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1464b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1465b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1466b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1467b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1468b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1469b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1470a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14712a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14722a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1473bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1476cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
147782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    const bool resizePending = (c.requested.w != c.active.w) ||
147882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            (c.requested.h != c.active.h);
14790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14809e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
14820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
14830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
14840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
14850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
14860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
14870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
14880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
14899e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
14909e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
14919e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
14929e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
14930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
14950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
14960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
14970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
149813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
149913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
150013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
150113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
15027d05257585918bd578bc0bc18f32571a48a7304aPablo Ceballos        Layer::State& editCurrentState(getCurrentState());
150382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        if (mFreezePositionUpdates) {
150482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float tx = c.active.transform.tx();
150582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float ty = c.active.transform.ty();
150682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
150782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active.transform.set(tx, ty);
150882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = c.active;
150982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        } else {
151082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = editCurrentState.requested;
151182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
151282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        }
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
151413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
151713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
15201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
152113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
152213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
152313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
152413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
152513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
15263dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
15273dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
152813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
152913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
153013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1531c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // If the layer is hidden, signal and clear out all local sync points so
1532c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // that transactions for layers depending on this layer's frames becoming
1533c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // visible are not blocked
1534c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    if (c.flags & layer_state_t::eLayerHidden) {
1535c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        Mutex::Autolock lock(mLocalSyncPointMutex);
1536c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        for (auto& point : mLocalSyncPoints) {
1537c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza            point->setFrameAvailable();
1538c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        }
1539c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        mLocalSyncPoints.clear();
1540c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
1541c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza
154213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
154305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    commitTransaction(c);
154413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::commitTransaction(const State& stateToCommit) {
154805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    mDrawingState = stateToCommit;
1549a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1550a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
155113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
155213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
155313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
155513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
155613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
155713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
155982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carrbool Layer::setPosition(float x, float y, bool immediate) {
15603dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
156113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
156213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
156369663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
156469663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
156569663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
156669663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15673dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
156882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    if (immediate && !mFreezePositionUpdates) {
156982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mCurrentState.active.transform.set(x, y);
157082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    }
157182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    mFreezePositionUpdates = mFreezePositionUpdates || !immediate;
157269663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
157413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
157513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
157613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
157782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr
157813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
157913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
158013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
158113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
158213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
158413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
158513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
158613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
158713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
158813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
158913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
159013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
159113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
15927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
159313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
159413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
159513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15969d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
15979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
15989d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
15999d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglardbool Layer::setAlpha(uint8_t alpha) {
16009d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
160113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
160213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
160313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
160413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
16057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
160613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
160713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
160813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
160913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
161013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
16113dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
161213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
16137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
161413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
161513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
161613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
161713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
16182ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
16197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
162013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
162113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
162213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
162313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
162413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
162513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
162613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
162713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
162813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
16297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
16307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
163113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
163213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
163313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
163499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
163599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carrbool Layer::setCrop(const Rect& crop, bool immediate) {
1636b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
163713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
163813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
163999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    mCurrentState.requestedCrop = crop;
164099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    if (immediate) {
164199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        mCurrentState.crop = crop;
164299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    }
16437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
164413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
164513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
164613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1647acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1648b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1649acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1650acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1651b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1652acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1653acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1654acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1655acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
165613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1657c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carrbool Layer::setOverrideScalingMode(int32_t scalingMode) {
1658c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (scalingMode == mOverrideScalingMode)
1659c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        return false;
1660c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    mOverrideScalingMode = scalingMode;
166182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    setTransactionFlags(eTransactionNeeded);
1662c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return true;
1663c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1664c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
1665c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carruint32_t Layer::getEffectiveScalingMode() const {
1666c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (mOverrideScalingMode >= 0) {
1667c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr      return mOverrideScalingMode;
1668c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    }
1669c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return mCurrentScalingMode;
1670c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1671c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
167213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
167313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
167413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
167513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
167613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
16777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
167813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
167913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1680a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1681a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
16827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
16837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
16847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
16857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
16867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
16877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
16887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
16897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1690792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1691792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
16927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
16937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
16947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1695ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1696ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1697ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1698ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1699ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1700ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1701ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1702ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1703ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1704ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1705ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1706ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17116b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1712ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1713d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1714d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1715d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
17166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
17170eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
17180eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
17190eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
17200eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
17216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
17226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
17230eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17240eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
17250eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
17260eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
17270eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
17280eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
17290eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
17300eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
17310eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
17326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
17336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1734d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonbool Layer::onPreComposition(nsecs_t refreshStartTime) {
1735d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    if (mBufferLatched) {
1736d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        Mutex::Autolock lock(mFrameEventHistoryMutex);
1737d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
1738d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
17394d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1740ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
174199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
174299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1743d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonbool Layer::onPostComposition(sp<Fence> glDoneFence) {
1744d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    // mFrameLatencyNeeded is true when a new frame was latched for the
1745d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    // composition.
1746e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    bool frameLatencyNeeded = mFrameLatencyNeeded;
1747d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1748d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const HWComposer& hwc = mFlinger->getHwComposer();
1749d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson#ifdef USE_HWC2
1750d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> retireFence = Fence::NO_FENCE;
1751d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> presentFence = Fence::NO_FENCE;
1752d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> presentOrRetireFence = Fence::NO_FENCE;
1753d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        if (hwc.retireFenceRepresentsStartOfScanout()) {
1754d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1755d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            presentOrRetireFence = presentFence;
1756d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        } else {
1757d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            retireFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1758d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            presentOrRetireFence = retireFence;
1759d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        }
1760d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        bool wasGpuComposited = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
1761d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
1762d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                HWC2::Composition::Client : true;
1763d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson#else
1764d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> retireFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1765d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> presentFence = Fence::NO_FENCE;
1766d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        sp<Fence> presentOrRetireFence = retireFence;
1767d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        bool wasGpuComposited = mIsGlesComposition;
1768d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson#endif
1769d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
1770d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        // Update mFrameEventHistory.
1771d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        {
1772d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            Mutex::Autolock lock(mFrameEventHistoryMutex);
1773d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            mFrameEventHistory.addPostComposition(mCurrentFrameNumber,
1774d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    wasGpuComposited ? glDoneFence : Fence::NO_FENCE,
1775d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    presentFence);
1776d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            mFrameEventHistory.addRetire(mPreviousFrameNumber,
1777d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    retireFence);
1778d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        }
1779d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
1780d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        // Update mFrameTracker.
1781bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
178282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
178382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1784bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1785789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
178682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
178782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
178882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
178982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
179082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
179182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
179282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1793d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        if (presentOrRetireFence->isValid()) {
1794d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            mFrameTracker.setActualPresentFence(presentOrRetireFence);
179582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
179682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
179782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
179882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
179982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
180082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
180182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
180282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1803d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1804d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1805e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return frameLatencyNeeded;
1806d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1807d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
18089d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
18099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
18109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
1811d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    Mutex::Autolock lock(mFrameEventHistoryMutex);
1812d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mFrameEventHistory.addRelease(mPreviousFrameNumber,
1813d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
18149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
18159d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
18169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1817da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
181813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
18199d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
18209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
18219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
18229d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
18239d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
18249d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            && (mActiveBuffer != NULL || mSidebandStream != NULL);
18259d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
1826da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1827da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1828cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglardbool Layer::allTransactionsSignaled() {
1829cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    auto headFrameNumber = getHeadFrameNumber();
1830cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    bool matchingFramesFound = false;
1831cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    bool allTransactionsApplied = true;
1832cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    Mutex::Autolock lock(mLocalSyncPointMutex);
1833cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard
1834cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    for (auto& point : mLocalSyncPoints) {
1835cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        if (point->getFrameNumber() > headFrameNumber) {
1836cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard            break;
1837cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        }
1838cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        matchingFramesFound = true;
1839cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard
1840cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        if (!point->frameIsAvailable()) {
1841cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           // We haven't notified the remote layer that the frame for
1842cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           // this point is available yet. Notify it now, and then
1843cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           // abort this attempt to latch.
1844cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           point->setFrameAvailable();
1845cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           allTransactionsApplied = false;
1846cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard           break;
1847cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        }
1848cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard
1849cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard        allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied();
1850cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    }
1851cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    return !matchingFramesFound || allTransactionsApplied;
1852cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard}
1853cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard
1854d6927fb1143398370c0885844bfb58923ef740b7Brian AndersonRegion Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime)
1855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18561c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
18571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1858399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1859399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1860399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
186112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
186212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
186312e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
186412e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
18655bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
18665bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
18675bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
18683dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1869399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1870399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
18714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1872223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mQueuedFrames <= 0 && !mAutoRefresh) {
1873223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1874223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
187599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1876223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // if we've already called updateTexImage() without going through
1877223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // a composition step, we have to skip this layer at this point
1878223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // because we cannot call updateTeximage() without a corresponding
1879223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // compositionComplete() call.
1880223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // we'll trigger an update in onPreComposition().
1881223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mRefreshPending) {
1882223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1883223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
18841ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1885223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // If the head buffer's acquire fence hasn't signaled yet, return and
1886223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // try again later
1887223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (!headFenceHasSignaled()) {
1888223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1889223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1890223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
18912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1892223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Capture the old state of the layer for comparisons later
1893223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const State& s(getDrawingState());
1894223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const bool oldOpacity = isOpaque(s);
1895223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1896223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1897cd6fd5463d2e9b87504e29a39ac5f2395010805bFabien Sanglard    if (!allTransactionsSignaled()) {
1898223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1899223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1900223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1901223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1902223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // This boolean is used to make sure that SurfaceFlinger's shadow copy
1903223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // of the buffer queue isn't modified when the buffer queue is returning
1904223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // BufferItem's that weren't actually queued. This can happen in shared
1905223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // buffer mode.
1906223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    bool queuedBuffer = false;
19077b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
19087b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                    getProducerStickyTransform() != 0, mName.string(),
19097b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                    mOverrideScalingMode, mFreezePositionUpdates);
1910223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1911223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
1912223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mLastFrameNumberReceived);
1913223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (updateResult == BufferQueue::PRESENT_LATER) {
1914223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Producer doesn't want buffer to be displayed yet.  Signal a
1915223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // layer update so we check again at the next opportunity.
1916223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1917223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1918223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1919223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // If the buffer has been rejected, remove it from the shadow queue
1920223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // and return early
1921063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
19226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1923223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mQueueItems.removeAt(0);
1924223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_dec(&mQueuedFrames);
1925223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
1926223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1927223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1928223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // This can occur if something goes wrong when trying to create the
1929223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // EGLImage for this buffer. If this happens, the buffer has already
1930223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // been released, so we need to clean up the queue and bug out
1931223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // early.
1932223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        if (queuedBuffer) {
1933223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            Mutex::Autolock lock(mQueueItemLock);
1934223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            mQueueItems.clear();
1935223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_and(0, &mQueuedFrames);
1936223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        }
1937ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1938223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Once we have hit this state, the shadow queue may no longer
1939223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // correctly reflect the incoming BufferQueue's contents, so even if
1940223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // updateTexImage starts working, the only safe course of action is
1941223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // to continue to ignore updates.
1942223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mUpdateTexImageFailed = true;
1943ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1944223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1945223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1946223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1947223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (queuedBuffer) {
1948223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Autolock scope
1949223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1950223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1951223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Mutex::Autolock lock(mQueueItemLock);
1952223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1953223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // Remove any stale buffers that have been dropped during
1954223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // updateTexImage
1955223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
19566b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
1957223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            android_atomic_dec(&mQueuedFrames);
19586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
19596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1960223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mQueueItems.removeAt(0);
1961223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1962ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1964223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Decrement the queued-frames count.  Signal another event if we
1965223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // have more frames pending.
1966223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1967223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            || mAutoRefresh) {
1968223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mFlinger->signalLayerUpdate();
1969223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1970d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1971223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // update the active buffer
1972223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1973223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (mActiveBuffer == NULL) {
1974223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        // this can only happen if the very first buffer was rejected.
1975223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        return outDirtyRegion;
1976223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
1977702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1978d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mBufferLatched = true;
1979d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mPreviousFrameNumber = mCurrentFrameNumber;
1980d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1981d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
1982d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    {
1983d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        Mutex::Autolock lock(mFrameEventHistoryMutex);
1984d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
1985d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson#ifndef USE_HWC2
1986d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mFrameEventHistory.addRelease(mPreviousFrameNumber,
1987d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
1988d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson#endif
1989d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
1990d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
1991223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mRefreshPending = true;
1992223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mFrameLatencyNeeded = true;
1993223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldActiveBuffer == NULL) {
1994223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard         // the first time we receive a buffer, we need to trigger a
1995223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard         // geometry invalidation.
1996223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
1997223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard     }
1998223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
1999223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
2000223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
2001223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
2002223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if ((crop != mCurrentCrop) ||
2003223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        (transform != mCurrentTransform) ||
2004223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        (scalingMode != mCurrentScalingMode))
2005223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    {
2006223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentCrop = crop;
2007223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentTransform = transform;
2008223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        mCurrentScalingMode = scalingMode;
2009223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2010223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2011702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2012223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldActiveBuffer != NULL) {
2013223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        uint32_t bufWidth  = mActiveBuffer->getWidth();
2014223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        uint32_t bufHeight = mActiveBuffer->getHeight();
2015223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        if (bufWidth != uint32_t(oldActiveBuffer->width) ||
2016223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            bufHeight != uint32_t(oldActiveBuffer->height)) {
2017702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
2018702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2019223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2020702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2021223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
2022223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    if (oldOpacity != isOpaque(s)) {
2023223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        recomputeVisibleRegions = true;
2024223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2025cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2026223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // Remove any sync points corresponding to the buffer which was just
2027223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // latched
2028223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    {
2029223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        Mutex::Autolock lock(mLocalSyncPointMutex);
2030223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        auto point = mLocalSyncPoints.begin();
2031223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard        while (point != mLocalSyncPoints.end()) {
2032223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if (!(*point)->frameIsAvailable() ||
2033223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                    !(*point)->transactionIsApplied()) {
2034223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // This sync point must have been added since we started
2035223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                // latching. Don't drop it yet.
2036223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                ++point;
2037223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                continue;
2038223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            }
2039223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2040223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2041223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                point = mLocalSyncPoints.erase(point);
2042223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard            } else {
2043223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard                ++point;
2044cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2045cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2046223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    }
2047cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2048223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // FIXME: postedRegion should be dirty & bounds
2049223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    Region dirtyRegion(Rect(s.active.w, s.active.h));
2050223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard
2051223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    // transform the dirty region to window-manager space
2052223eb91c416f4acb3e635f1dccf5e5ba74c0d866Fabien Sanglard    outDirtyRegion = (s.active.transform.transform(dirtyRegion));
20531c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
20544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
205713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
205813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
205913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
206013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
206113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
206213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
206313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
206403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
206503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
206603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
206713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
206813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
206913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
207013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
207113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
207213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
207313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
207413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
207513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
207613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
207713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
207813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
207913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
208013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
208113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
208213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
208313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
208413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
208513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
208613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
208713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
208813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
208913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
20911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
20921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
209313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
209574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
209613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
209713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
20983e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
209913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21002ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
210113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2102ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
210313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
210413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
210574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2106acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2107acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
210813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
21099d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
21109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21119d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#else
21129d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21139d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
211413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
21153dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2116b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2117b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2118b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2119b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
21204125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
212113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
21223dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
21233dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
212413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
21251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2127a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
21281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
21291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
21301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
21311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2132a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
21331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
213474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
21351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2136ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
21376905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2138a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
21396905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
21401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2141bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
21423d1d280fa3cbc30700f728a4b13e5308315433d3Colin Cross        mSurfaceFlingerConsumer->dumpState(result, "            ");
2143bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2144d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2145d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
21469d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#ifdef USE_HWC2
2147e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDumpHeader(String8& result) {
2148e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2149e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2150e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Layer name\n");
2151e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("           Z | ");
2152e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append(" Comp Type | ");
2153e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("  Disp Frame (LTRB) | ");
2154e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("         Source Crop (LTRB)\n");
2155e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("----------------------------------------");
2156e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("---------------------------------------\n");
2157e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
2158e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2159e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stozavoid Layer::miniDump(String8& result, int32_t hwcId) const {
2160e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
2161e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        return;
2162e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2163e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2164e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    String8 name;
2165e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    if (mName.length() > 77) {
2166e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        std::string shortened;
2167e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string(), 36);
2168e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append("[...]");
2169e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        shortened.append(mName.string() + (mName.length() - 36), 36);
2170e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = shortened.c_str();
2171e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    } else {
2172e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        name = mName;
2173e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
2174e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2175e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat(" %s\n", name.string());
2176e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2177e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Layer::State& layerState(getDrawingState());
2178e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
2179e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("  %10u | ", layerState.z);
2180e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%10s | ",
2181e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            to_string(getCompositionType(hwcId)).c_str());
2182e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const Rect& frame = hwcInfo.displayFrame;
2183e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top,
2184e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            frame.right, frame.bottom);
2185e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    const FloatRect& crop = hwcInfo.sourceCrop;
2186e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top,
2187e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            crop.right, crop.bottom);
2188e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2189e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - - ");
2190e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("- - - - - - - - - - - - - - - - - - - -\n");
2191e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza}
21929d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard#endif
2193e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
2194d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2195d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
219682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
219782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2198d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2199d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
220025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
220125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
22026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
22036547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
22046547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
22056547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2206d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2207d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2208d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2209d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
2210d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid Layer::dumpFrameEvents(String8& result) {
2211d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("- Layer %s (%s, %p)\n",
2212d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson            getName().string(), getTypeId(), this);
2213d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    Mutex::Autolock lock(mFrameEventHistoryMutex);
2214d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mFrameEventHistory.checkFencesForCompletion();
2215d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    mFrameEventHistory.dump(result);
2216d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
2217d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
22183890c3995c4a52439844faeb80b5503d42b977d8Brian Andersonvoid Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
22193890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEventHistoryDelta *outDelta) {
2220d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    Mutex::Autolock lock(mFrameEventHistoryMutex);
2221d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    if (newTimestamps) {
2222d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        mFrameEventHistory.addQueue(*newTimestamps);
2223d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
222440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
22253890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson    if (outDelta) {
22263890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        mFrameEventHistory.getAndResetDelta(outDelta);
2227d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
222840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
2229e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2230e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastd::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
2231e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool forceFlush) {
2232e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::vector<OccupancyTracker::Segment> history;
2233e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush,
2234e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            &history);
2235e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    if (result != NO_ERROR) {
2236e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(),
2237e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                result);
2238e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        return {};
2239e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2240e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return history;
2241e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2242e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2243367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carrbool Layer::getTransformToDisplayInverse() const {
2244367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
2245367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr}
2246367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr
224713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
224813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
22523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
22533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
22563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
22573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2258