Layer.cpp revision 468051e20be19130572231266db306396a56402b
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza//#define LOG_NDEBUG 0
189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#undef LOG_TAG
199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#define LOG_TAG "Layer"
201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
211c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
29a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
33399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
373330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
399cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h>
4190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
450f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
47b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
511b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
52875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
53875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
54c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza#include <mutex>
55c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
7013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
7113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
7213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
7313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStateMutex(),
757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStates(),
76a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
77399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
78a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
79933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
80c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        mOverrideScalingMode(-1),
81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
82cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
834d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
8482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
8513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
875cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifndef USE_HWC2
8940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        mIsGlesComposition(false),
9040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
9113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
9213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
9303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
94a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
95a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
96a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
97a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
9865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9904839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
10082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mAutoRefresh(false),
10182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mFreezePositionUpdates(false)
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
107a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
10949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1134125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1154125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
116231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
117231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1263dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.active.transform.set(0, 0);
127b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop.makeInvalid();
128b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop.makeInvalid();
1294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
152e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
153e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
155bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
156b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
157b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
158468051e20be19130572231266db306396a56402bIrvel    BufferQueue::createBufferQueue(&producer, &consumer, nullptr, true);
159b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
160468051e20be19130572231266db306396a56402bIrvel    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
162399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
164b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
165c9d972065c44860306add0172b5185bd8611f9eeDan Stoza#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
16619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
167303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1686905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
171b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17296f0819f81293076e652792794a961543e6750d7Mathias Agopian
1734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1748ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1758ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1768ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1778ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1788ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
179cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
180cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
181cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
182c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    for (auto& point : mLocalSyncPoints) {
183c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        point->setFrameAvailable();
184c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
185921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
18796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
18896f0819f81293076e652792794a961543e6750d7Mathias Agopian
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
2009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
201c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
20513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
2089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
214468051e20be19130572231266db306396a56402bIrvel        mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
215468051e20be19130572231266db306396a56402bIrvel                item.mGraphicBuffer->getHeight(), item.mFrameNumber);
216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
225a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
226a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
232ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
233a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
234a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
235a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
236a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
23999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
240579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
241579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2426b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
245a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
253a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
254a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2594d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
2607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
267399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
268399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
269399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
270399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
271399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
272399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
273399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
278bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
27948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
280cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
324582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
325582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
326b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
327b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
334a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
335a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
336a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
337f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
338f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
339a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
340f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
341a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
342a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
343a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
344f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
345a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
347f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
348f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
349f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
350f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
351f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
352f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
353f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
354f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
355f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
356f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
357f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
358f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
359f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
360f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
36113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3636c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3646c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3656c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3666c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3676c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
36813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
369b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
370b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
371b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3736c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3776b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3806b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
38113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
382b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
38313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3896b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3906b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3916b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3920e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3930e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
394b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
395b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
3960e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3970e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3983dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
399acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
400acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
401acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
402b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
403b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
404acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
405acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
406acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4073dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
41028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
41128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
41228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
41328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
41428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
415acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
416acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
417acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
419f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
420f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
421f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
422acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
423acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
424acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
425acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
428021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
429021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
430acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
431021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransformOrient =
432021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
436acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
43713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
438acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
4390f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        invTransform = (Transform(invTransformOrient) * Transform(invTransform))
4400f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos                .getOrientation();
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
442acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
443acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
446acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
447acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
448acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
449acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
450acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
451acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
452acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
453acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
454acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
455acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
456acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
457acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
458acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
46213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
465acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
469acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
47613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
47713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
47813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
47913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
4834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
487a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
49213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
4939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
494a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4953e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5053e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
506a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
507dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
508dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
509dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
511dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5244125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
52513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
52613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
52813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
53113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
53213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5336c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
534b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
535b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5363dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
538acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
540acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
542acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
543acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5443dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.inverse().transform(activeCrop);
54528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
54628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
54728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
54828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
54928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
55028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
551acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
552acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
553acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5606c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5616c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5626c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5633dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
564b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
565b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
566acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
567acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
568acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
570acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
571acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
572acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
5769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
5779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
5789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.top, transformedFrame.right,
5799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.bottom, to_string(error).c_str(),
5809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
5839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
5849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.left, sourceCrop.top, sourceCrop.right,
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.bottom, to_string(error).c_str(),
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
5969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
5979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
600acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(hw->getViewport(), &frame)) {
601acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
602acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
6069f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
6079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6089f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
60929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
61029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
61129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
61229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
61329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
61429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
61529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
61629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
61729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6183dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
619c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
620c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
621c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
622021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
623021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
624c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
625021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransform =
626021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
627c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
628c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
629c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
630c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
631c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
632c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6330f5131fe72f3e7ca599946536d1f6028bb93398dPablo Ceballos        transform = Transform(invTransform) * transform;
634c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
63529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
63629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
63713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
6523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
653a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
65413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
655a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
6569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
657a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
658a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
6799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6930f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Sideband layers
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
6950f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Sideband);
6960f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Sideband composition", mName.string());
6970f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7030f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7060f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Client or SolidColor layers
7070f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr ||
7080f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza            mHwcLayers[hwcId].forceClientComposition) {
7090f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        // TODO: This also includes solid color layers, but no API exists to
7100f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        // setup a solid color layer yet
7110f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Client composition", mName.string());
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7130f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        return;
7140f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7150f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7160f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    // Device or Cursor layers
7170f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (mPotentialCursor) {
7180f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGV("[%s] Requesting Cursor composition", mName.string());
7190f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Cursor);
7209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7240f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza
7250f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7260f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
7270f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    if (error != HWC2::Error::None) {
7280f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7290f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                mActiveBuffer->handle, to_string(error).c_str(),
7300f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza                static_cast<int32_t>(error));
7310f67b3f01fc74bbd8cf4be24fce4a1e42f102282Dan Stoza    }
7329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
7344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
735d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
73613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
73913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
74013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
74113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
74213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
744db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
74540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
746ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
747399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
748399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
749399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
750399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
751399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
752399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
753399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
754c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
7559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
767dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
7689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
7709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
771b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
772b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
7739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
7759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
776baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
7779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
778b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
779b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
780acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
7819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
7829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
7839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
7859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
7869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
7879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
7889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
792c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
793d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
794c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
795d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
796d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
797d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
798d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
79903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
800bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8011df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
802c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
803dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
804dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
805dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
806dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
807dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
808c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
809c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
810c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
81103414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
81203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
81303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
81403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
81503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
81603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
81703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
81803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
81903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
820b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
821b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
82203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
82303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
82403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
8253dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(bounds));
82603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
827b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
828b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
829acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
83003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
83103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
83203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
8339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
83403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
840c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
843c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
844c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
845c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
848c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
849c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
850c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
851c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
852c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
853c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8561c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
857a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
859179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
860179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
861179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
862179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
863179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
864179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
865179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
866179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
867179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
868f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
869f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
870179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
871179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
874179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
8754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
876179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
877179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
878179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
879179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
8801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
881179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
884a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
88597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
88697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
887bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
888bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
88997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
890dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
891dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
892dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
893dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
894dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
895dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
896875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
897875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
898dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
899cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
900eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
901cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
902cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
903cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
904bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
905bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
906cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
907c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
908c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
909c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
910021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the code below applies the primary display's inverse transform to
911021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the texture transform
912c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
913c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
914c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
915c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
916c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
917c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
918c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
919c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
920021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos            uint32_t transform =
921021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                    DisplayDevice::getPrimaryDisplayOrientationTransform();
922c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
923c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
924c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
925c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
926c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
927c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
928c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
929c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
930c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
931c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
932c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
933c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
934c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
935c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
936c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
937cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
93849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
93949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
94049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
94149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
94249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
943a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
944875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
945a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
946c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
947875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
951c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
952c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
953c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
95519733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
956c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
95719733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
95819733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
95913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
96313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
96413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
96513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
966c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
967c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
9681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
96913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
970c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
97113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
97313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
97413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
97513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
97613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
981c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
986acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
987acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
988b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
989acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
990b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
991acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
992acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
993acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
994acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
995acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
996acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
997acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1004875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1005875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1006ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1007ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1008ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1009ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1010ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1012875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10134125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10145cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1015875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
10199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
10439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getCompositionType called without a valid HWC layer");
10459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10671681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
10681681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
10691681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
10701681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
10711681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
10721681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
10731681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
10741681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
10751681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
10761681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
10771681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1078c5da271eec001da9e11a2786f2618a45257439c3Dan Stozabool Layer::latchUnsignaledBuffers() {
1079c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool propertyLoaded = false;
1080c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static bool latch = false;
1081c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    static std::mutex mutex;
1082c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    std::lock_guard<std::mutex> lock(mutex);
1083c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (!propertyLoaded) {
1084c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        char value[PROPERTY_VALUE_MAX] = {};
1085c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        property_get("debug.sf.latch_unsignaled", value, "0");
1086c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        latch = atoi(value);
1087c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        propertyLoaded = true;
1088c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1089c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    return latch;
1090c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza}
1091c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
1092cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1093cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1094cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1095cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1096cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1097cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
10987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1099cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
11011ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stozabool Layer::headFenceHasSignaled() const {
11021ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#ifdef USE_HWC2
1103c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    if (latchUnsignaledBuffers()) {
1104c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza        return true;
1105c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    }
1106c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
11071ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
11081ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems.empty()) {
11091ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11101ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11111ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    if (mQueueItems[0].mIsDroppable) {
11121ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // Even though this buffer's fence may not have signaled yet, it could
11131ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // be replaced by another buffer before it has a chance to, which means
11141ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // that it's possible to get into a situation where a buffer is never
11151ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // able to be latched. To avoid this, grab this buffer anyway.
11161ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        return true;
11171ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    }
11181ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
11191ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#else
11201ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    return true;
11211ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza#endif
11221ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza}
11231ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1124cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1125cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1131cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1132cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1133cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1144ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1145ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1146ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1147ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1148ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1149ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1150ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11515773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1154ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11555773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11565773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11575773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1158dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11595773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11605773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1161dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1162ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1163ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1168acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1169acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1170acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1171acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1172acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1173acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1174acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1175acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1176acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1177acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1178acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1179acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1180acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1181acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1182acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1183c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1184c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
11861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1187acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1190b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1191b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
11936c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1194f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
11953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1196acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1197acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1198acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1199acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1200acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1201acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1202acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1203acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1204acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1205acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1206acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1207acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1208b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1209b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1210b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1211b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1212b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1213acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1214acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1215ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1216acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1217acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1218acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1219acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12215cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
122313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1224ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12254125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1226a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1227a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1228a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1229db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1230a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1231db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1232a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1233a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1234a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12354125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1236a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1237a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1238231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1239231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1240231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1241231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1242231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1243231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12447a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12457a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1246a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12477a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12487a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12497a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1250b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
125113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
1252c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
125313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
125613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
125713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
126013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
126113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
126413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
126513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
126613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
126913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
127013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
127113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
127213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
127313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
127413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
127513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
127613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
127713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
127813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
127913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
128013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
128113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
128213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
12847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
12857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
12867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
12897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
12907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
12917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
12927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
12937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
12947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
12957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
12967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
12977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
12987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
12993bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
13003bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
13013bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1302cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1303cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1304cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1305cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1306cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1307cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1308cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
131705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::popPendingState(State* stateToCommit) {
131805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    auto oldFlags = stateToCommit->flags;
131905289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    *stateToCommit = mPendingStates[0];
132005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
132105289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            (stateToCommit->flags & stateToCommit->mask);
13227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
132605289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosbool Layer::applyPendingStates(State* stateToCommit) {
13277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
133505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1340cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1341cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1342cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1343cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1344cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1345cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1346cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1347cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1348cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1349cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1350cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
13527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
135305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
13577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
13587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1359792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1360792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
13617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
136305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            popPendingState(stateToCommit);
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
13717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
13737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
13767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
13777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1380cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
13811ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza    bool headFenceSignaled = headFenceHasSignaled();
1382cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1383cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
13841ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
1385cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1386cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
13877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
139013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
13911c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
139405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    Layer::State c = getCurrentState();
139505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    if (!applyPendingStates(&c)) {
13967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
13977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
14021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1403a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1404a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1405cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14069d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14076905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1408419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1409b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1410419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1411b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
1412c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                this, getName().string(), mCurrentTransform,
1413c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getEffectiveScalingMode(),
14141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1415b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1416b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1417b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1418b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1419b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1420b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1423b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1424b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1425b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1426b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1427b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1428b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1429b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14312a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14322a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1433bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1436cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
143782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    const bool resizePending = (c.requested.w != c.active.w) ||
143882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            (c.requested.h != c.active.h);
14390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14409e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
144113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
14420cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
14430cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
14440cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
14450cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
14460cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
14470cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
14480cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
14499e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
14509e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
14519e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
14529e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
14530cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14540cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
14550cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
14560cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
14570cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
145813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
145913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
146013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
146113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
14627d05257585918bd578bc0bc18f32571a48a7304aPablo Ceballos        Layer::State& editCurrentState(getCurrentState());
146382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        if (mFreezePositionUpdates) {
146482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float tx = c.active.transform.tx();
146582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            float ty = c.active.transform.ty();
146682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
146782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active.transform.set(tx, ty);
146882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = c.active;
146982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        } else {
147082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            editCurrentState.active = editCurrentState.requested;
147182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            c.active = c.requested;
147282364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        }
147313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
147613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
147713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
147813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
147913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
148213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
148313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
148413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
148513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
14863dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
14873dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
148813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
148913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
149013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1491c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // If the layer is hidden, signal and clear out all local sync points so
1492c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // that transactions for layers depending on this layer's frames becoming
1493c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    // visible are not blocked
1494c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    if (c.flags & layer_state_t::eLayerHidden) {
1495c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        Mutex::Autolock lock(mLocalSyncPointMutex);
1496c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        for (auto& point : mLocalSyncPoints) {
1497c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza            point->setFrameAvailable();
1498c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        }
1499c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza        mLocalSyncPoints.clear();
1500c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza    }
1501c8145170a4b3bfdcfd6bd08b61ad55ae4eac9cc9Dan Stoza
150213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
150305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    commitTransaction(c);
150413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
150705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::commitTransaction(const State& stateToCommit) {
150805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    mDrawingState = stateToCommit;
1509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
151113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
151413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
151713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
151982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carrbool Layer::setPosition(float x, float y, bool immediate) {
15203dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
152113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
152213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
152369663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
152469663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
152569663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
152669663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15273dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
152882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    if (immediate && !mFreezePositionUpdates) {
152982364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr        mCurrentState.active.transform.set(x, y);
153082364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    }
153182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    mFreezePositionUpdates = mFreezePositionUpdates || !immediate;
153269663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
153413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
153513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
153613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
153782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr
153813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
153913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
154013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
154113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
154213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
154413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
154513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
154613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
154713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
154813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
154913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
155013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
155113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
15527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
155313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
155413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
155513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
15579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
15589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
155913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
15609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
156113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
156213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
156313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
156413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
156613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
156713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
156813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
156913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
157013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
15713dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
157213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
15737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
157413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
157513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
157613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
157713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
15782ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
15797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
158013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
158113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
158213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
158313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
158413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
158513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
158613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
158713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
158813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
15897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
15907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
159113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
159213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
159313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
159499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
159599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carrbool Layer::setCrop(const Rect& crop, bool immediate) {
1596b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
159713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
159813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
159999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    mCurrentState.requestedCrop = crop;
160099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    if (immediate) {
160199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        mCurrentState.crop = crop;
160299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr    }
16037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
160413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
160513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
160613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1607acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1608b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1609acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1610acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1611b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1612acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1613acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1614acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1615acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
161613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1617c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carrbool Layer::setOverrideScalingMode(int32_t scalingMode) {
1618c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (scalingMode == mOverrideScalingMode)
1619c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        return false;
1620c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    mOverrideScalingMode = scalingMode;
162182364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr    setTransactionFlags(eTransactionNeeded);
1622c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return true;
1623c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1624c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
1625c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carruint32_t Layer::getEffectiveScalingMode() const {
1626c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (mOverrideScalingMode >= 0) {
1627c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr      return mOverrideScalingMode;
1628c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    }
1629c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return mCurrentScalingMode;
1630c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1631c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
163213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
163313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
163413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
163613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
16377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
163813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
163913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1640a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1641a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
16427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
16437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
16447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
16457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
16467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
16477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
16487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
16497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1650792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1651792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
16527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
16537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
16547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1655ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1656ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1657ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1658ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1659ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1660ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1661ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1662ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1663ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1664ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1665ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1666ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16716b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1672ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1673d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1674d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1675d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
16766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
16770eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
16780eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
16790eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
16800eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
16816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
16826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
16830eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16840eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
16850eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
16860eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
16870eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
16880eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
16890eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16900eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
16910eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
16926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
16936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
16944d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
16954d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1696ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
169799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
169899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1699e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozabool Layer::onPostComposition() {
1700e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    bool frameLatencyNeeded = mFrameLatencyNeeded;
1701d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1702bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
170382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
170482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1705bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1706789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
170782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
170882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
170982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
171082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
171182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
171282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
171382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1714d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
17159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
17179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
171882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
17199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1720789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
172182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
172282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
172382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
172482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
172582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
172682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
172782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
172882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
172982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1730d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1731d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1732e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return frameLatencyNeeded;
1733d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1734d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
17359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
17389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
17399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
17409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1741da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
174213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
17439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
17459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
174713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1748afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1750da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1751da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
17524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17541c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
17551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1756399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1757399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1758399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
175912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
176012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
176112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
176212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
17635bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
17645bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
17655bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
17663dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1767399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1768399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
17694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1770ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mQueuedFrames > 0 || mAutoRefresh) {
177199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
177299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
177399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
177499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
177599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
177699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
17774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
17784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
177999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
178099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
17811ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // If the head buffer's acquire fence hasn't signaled yet, return and
17821ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        // try again later
17831ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        if (!headFenceHasSignaled()) {
17841ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza            mFlinger->signalLayerUpdate();
17851ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza            return outDirtyRegion;
17861ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza        }
17871ce6581ac788eaad58fd3329c2154af7dd74aa3dDan Stoza
1788351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
17894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
17904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1791351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1792db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1793bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
17942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
17952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
17962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
17971681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
1798b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            const char* name;
1799c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            int32_t overrideScalingMode;
1800a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr            bool& freezePositionUpdates;
1801b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
18022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
1803b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                    bool& recomputeVisibleRegions, bool stickySet,
1804c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                    const char* name,
1805a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                    int32_t overrideScalingMode,
1806a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                    bool& freezePositionUpdates)
18072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
18081681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
1809b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                  stickyTransformSet(stickySet),
1810c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                  name(name),
1811a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                  overrideScalingMode(overrideScalingMode),
1812a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                  freezePositionUpdates(freezePositionUpdates) {
18132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
18142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
181611611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
18172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
18182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
18192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
18222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
18232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
18252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
18262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
18272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
18282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1830c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                int actualScalingMode = overrideScalingMode >= 0 ?
1831c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                        overrideScalingMode : item.mScalingMode;
1832c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
18332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
18342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
18362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
18372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
18382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
18392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
18402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
18412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
18422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
18432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
18452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
18462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
18472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
18482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
18492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
18502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
185139c88e8c7d870486f703408dafd0a62e7420df05Pablo Ceballos                        current.modified = true;
18522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
18542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
18552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
18562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
1858b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
18592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1860b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "            requested={ wh={%4u,%4u} }}\n",
1861b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            name,
18626905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
18632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
1864b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.left,
1865b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.top,
1866b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.right,
1867b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.bottom,
1868b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getWidth(),
1869b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getHeight(),
1870b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.requested.w, front.requested.h);
18712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18731681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
18742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
18752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
18764824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
1877b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                        ALOGE("[%s] rejecting buffer: "
1878b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1879b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                name, bufWidth, bufHeight, front.active.w, front.active.h);
18802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
18812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
18822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18832ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
18842ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
18852ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
18862ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
18872ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
18882ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
18892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
18902ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
18916c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18926c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
18936c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
18946c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
18956c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
18966c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
18976c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
18986c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
18996c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
19006c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
19012ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
19022ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
19032ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
190499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                if (front.crop != front.requestedCrop) {
190599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    front.crop = front.requestedCrop;
190699e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    current.crop = front.requestedCrop;
190799e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                    recomputeVisibleRegions = true;
190899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                }
1909a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                freezePositionUpdates = false;
191099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr
19112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
19122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
19132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
19142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19151681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1916c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getProducerStickyTransform() != 0, mName.string(),
1917a392073ff99c39b52bee88578c37d6a12235faf5Robert Carr                mOverrideScalingMode, mFreezePositionUpdates);
19182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
19197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1920cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1921cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1922cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1923cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1924cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1925cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1926cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
19277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1928cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1929cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1930cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
19317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
19327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1933cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
19347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1935cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1936cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1937cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1938cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1939cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1940cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1941cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1942cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1943cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1944cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1945cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
19467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1947a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1948a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1949cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
1950cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
1951cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
1952cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1953cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1954063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1955063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
19562dcb363c6e86b463a9f4e5925746e2f1089aef16Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in shared
1957063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1958063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
195941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1960ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
1961cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
19621585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
19631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
19641585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
19651585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
19661585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1967ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1968ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1969ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1970063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1971063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1972063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1973063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1974063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1975ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
197665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
197765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
197865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
197965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
198065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1981063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
198265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
198365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
198465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
198565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
198665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
198765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
198865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
198965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
199065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
199165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
199265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
199365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
19941585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
19951585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1996063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1997063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1998ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1999ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20006b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
2001ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
2002ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
2003ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
2004ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
2005ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
2006ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
2007ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
2008ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
20106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
20116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
2012ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
20131585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
20141585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
2015063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
2016ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                || mAutoRefresh) {
20171585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
20181585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
20191585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
20201585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
2021a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
2022a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
20234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
2024a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
2025d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
2026351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
2027bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
2028e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
2029e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
20304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
2031e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
2032da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
20334824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
2034702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
2035e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
20362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
20372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
2038ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
20392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
2040702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2041bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
2042bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
2043bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
2044702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
2045702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
2046702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
2047702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
2048702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
2049702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
2050702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
2051ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
2052702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2053702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2054702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
2055e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
2056e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
2057702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
2058702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
2059ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
2060702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
2061702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2062702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2063702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
20644125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
2065702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
2066702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2067702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2068cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2069cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2070cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
2071cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
2072cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
2073cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
2074cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
2075cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
2076cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
2077cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
2078cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
2079cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
2080cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2081cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
2082cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2083cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2084cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2085cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
2086cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
2087cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2088cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2089cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2090cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2091cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
20924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
20931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
20941c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
20954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
20963dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        outDirtyRegion = (s.active.transform.transform(dirtyRegion));
2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
210213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
210313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
210413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
210513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
210613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
210713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
210803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
210903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
211003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
211113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
211213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
211313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
211413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
211513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
211613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
211713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
211813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
211913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
212013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
212113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
212213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
212313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
212413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
212513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
212613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
212713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
212813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
212913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
213013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
213113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
213213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
213313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
21351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
21361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
213713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
213974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
214013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
214113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
21423e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
214313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
214513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2146ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
214713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
214813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
214974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2150acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2151acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
215213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
21549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
215613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
215813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
21593dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2160b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2161b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2162b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2163b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
21644125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
216513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
21663dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
21673dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
216813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
21691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2170a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2171a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
21721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
21731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
21741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
21751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2176a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
21771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
217874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
21791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2180ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
21816905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2182a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
21836905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
21841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2185bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
218674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
2187bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2188d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2189d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
2190d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2191d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
219282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
219382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2194d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2195d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
219625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
219725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
21986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
21996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
22006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
22016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2202d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2203d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2204d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2205d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
220640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
220740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        bool* outIsGlesComposition, nsecs_t* outPostedTime,
220840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
220940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outName = mName;
221040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
221140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
221240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifdef USE_HWC2
221340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
221440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
221540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            HWC2::Composition::Client : true;
221640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#else
221740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mIsGlesComposition;
221840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
221940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
222040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
222140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
222240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
2223e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2224e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastd::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
2225e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool forceFlush) {
2226e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::vector<OccupancyTracker::Segment> history;
2227e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush,
2228e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            &history);
2229e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    if (result != NO_ERROR) {
2230e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(),
2231e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                result);
2232e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        return {};
2233e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2234e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    return history;
2235e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2236e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2237367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carrbool Layer::getTransformToDisplayInverse() const {
2238367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
2239367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr}
2240367c5684f4d417e5176bec12d67f4e2e42738fe0Robert Carr
224113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
224213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
22463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
22473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
22503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
22513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2252