Layer.cpp revision 4d85da4a77203f4c361e48699e5598ebe8c77b32
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
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
7013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
7113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStateMutex(),
737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mPendingStates(),
74a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
75399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
76a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
77933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
78c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        mOverrideScalingMode(-1),
79a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
80cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
814d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
8282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
8313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
855cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifndef USE_HWC2
8740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        mIsGlesComposition(false),
8840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
8913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
9013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
9103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
92a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
93a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
94a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
95a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
9665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9704839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
98ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        mAutoRefresh(false)
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
10649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1104125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1114125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1124125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
113231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
114231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1233dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.active.transform.set(0, 0);
124b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop.makeInvalid();
125b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop.makeInvalid();
1264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
149e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
150e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
152bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
153b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
154b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
155b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
156b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
157b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
159399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
161b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1627f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1637f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1647f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
16519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
166303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1676905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
170b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17196f0819f81293076e652792794a961543e6750d7Mathias Agopian
1724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1738ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1748ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1758ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1768ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1778ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
178cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
179cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
180cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
181921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
18396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
18496f0819f81293076e652792794a961543e6750d7Mathias Agopian
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
197c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
20113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
2049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2066b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
210a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
211a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
212a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
213a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
214a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
215a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
225a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
227ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
231a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
23499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
235579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
236579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2376b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
240a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
248a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
249a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2544d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
2557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
262399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
263399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
264399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
265399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
266399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
267399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
268399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2696710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2716710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
273bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
27448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
275cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
3117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
3127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
3137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
3147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
3157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
3167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
3177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
3187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
336582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
337b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
338b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
34413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
345a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
346a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
347a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
348f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
349f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
350a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
351f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
352a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
353a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
354a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
355f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
356a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
358f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
359f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
360f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
361f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
362f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
363f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
364f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
365f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
366f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
367f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
368f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
369f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
370f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
371f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
37213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3776c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3786c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
380b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
381b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
382b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
38313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3846c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3856c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3886b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3916b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
393b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
39713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
39813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3996b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
4006b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
4016b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
4026b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
4030e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4040e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
405b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
406b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
4070e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
4080e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4093dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
410acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
411acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
412acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
413b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
414b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
415acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
416acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
417acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4183dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
42028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
42128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
42228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
42328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
42428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
42528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
428acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
430f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
431f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
432f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
436acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
437acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
438acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
439021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
440021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
442021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransformOrient =
443021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
446acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
447acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
448acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            // If the transform has been rotated the axis of flip has been swapped
449acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            // so we need to swap which flip operations we are performing
4507b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4517b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
452acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (is_h_flipped != is_v_flipped) {
4537b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4547b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4557b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
457acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
458acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
462acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
465acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
466acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
469acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
476acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
477acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
478acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
479acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
48013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
481acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
482acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
483acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
48413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
485acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
486acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
487acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
488acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
489acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
490acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
491acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
492acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
493acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
5024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
5034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
505a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
5099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
512a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
5133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5233e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
524a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
525dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
526dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
527dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
529dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5424125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
54313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
54413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
54513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
54813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
54913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
55013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
552b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
553b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5543dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
556acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
558acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
560acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
561acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5623dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.inverse().transform(activeCrop);
56328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
56428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
56528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
56628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
56728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
56828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
569acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
570acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
571acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5776c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5786c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5796c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5806c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5813dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
582b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
583b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
584acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
585acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
586acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
588acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
589acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
590acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
5969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.top, transformedFrame.right,
5979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.bottom, to_string(error).c_str(),
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.left, sourceCrop.top, sourceCrop.right,
6059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.bottom, to_string(error).c_str(),
6069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
6099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
6109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
6119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
6169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
618acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(hw->getViewport(), &frame)) {
619acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
620acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
62113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
62213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
62313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
6249f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
6259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6269f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
62729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
62829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
62929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
63029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
63129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
63229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
63329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
63429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
63529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6363dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
638c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
639c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
640021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * the code below applies the primary display's inverse transform to the
641021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos         * buffer
642c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
643021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos        uint32_t invTransform =
644021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                DisplayDevice::getPrimaryDisplayOrientationTransform();
645021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos
6461440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
647c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
648c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
649c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
650c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
6511440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
6521440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
6531440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
6541440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
6551440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
6561440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
6571440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
6581440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
659c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
660c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6611440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
662c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
66329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
66429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
66513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
67813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
67913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
6803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
681a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
68213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
683a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
685a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
686a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
7039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
7159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
7179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
7199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto compositionType = HWC2::Composition::Invalid;
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        compositionType = HWC2::Composition::Sideband;
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
7269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            return;
7309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
7339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            compositionType = HWC2::Composition::Client;
7349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
7359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
7379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        to_string(error).c_str(), static_cast<int32_t>(error));
7389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
7419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (mPotentialCursor) {
7429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                compositionType = HWC2::Composition::Cursor;
7439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
7469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    acquireFence);
7479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        mActiveBuffer->handle, to_string(error).c_str(),
7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        static_cast<int32_t>(error));
7519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // If it's not a cursor, default to device composition
7549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers[hwcId].forceClientComposition) {
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Forcing Client composition", mName.string());
7599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (compositionType != HWC2::Composition::Invalid) {
7619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting %s composition", mName.string(),
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(compositionType).c_str());
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, compositionType);
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
7704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
771d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
77513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
780db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
78140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
782ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
783399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
784399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
785399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
786399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
787399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
788399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
789399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
790c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
7929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
8029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
803dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
8049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
8059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
8069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
807b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
808b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
8099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
8119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
812baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
8139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
814b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
815b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
816acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
8179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
8189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
8199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
8219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
8229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
8239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
8249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
8259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
8269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
8279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
828c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
829d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
830c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
831d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
832d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
833d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
834d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
83503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
836bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8371df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
838c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
839dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
840dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
841dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
842dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
843dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
844c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
845c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
846c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
84703414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
84803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
84903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
85003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
85103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
85203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
85303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
85403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
85503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
856b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
857b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
85803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
85903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
86003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
8613dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(bounds));
86203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
863b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
864b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
865acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
86603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
86703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
86803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
8699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
87003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
876c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
880c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
881c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
884c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
885c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
886c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
887c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
888c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
889c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8911c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
893a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
895179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
896179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
897179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
898179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
899179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
900179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
901179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
902179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
903179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
904f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
905f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
906179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
907179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
90913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
910179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
9114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
912179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
913179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
914179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
915179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
9161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
917179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
920a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
92197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
92297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
923bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
924bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
92597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
926dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
927dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
928dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
929dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
930dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
931dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
932875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
933875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
934dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
935cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
936eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
937cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
938cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
939cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
940bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
941bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
942cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
943c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
944c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
945c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
946021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the code below applies the primary display's inverse transform to
947021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos             * the texture transform
948c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
949c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
950c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
951c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
952c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
953c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
954c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
955c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
956021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos            uint32_t transform =
957021623b5a82e44e8dc1a7def1abfed351187593cPablo Ceballos                    DisplayDevice::getPrimaryDisplayOrientationTransform();
958c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
959c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
960c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
961c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
962c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
963c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
964c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
965c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
966c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
967c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
968c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
969c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
970c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
971c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
972c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
973cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
97449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
97549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
97649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
97749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
97849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
979a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
980875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
981a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
982c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
983875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
987c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
988c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
989c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
99119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
992c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
99319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
99419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1002c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
1003c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
10041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1006c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
1017c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
1022acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
1023acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1024b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1025acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
1026b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
1027acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1028acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1029acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
1030acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
1031acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1032acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1033acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
103913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1040875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1041875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1042ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1043ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1044ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1045ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1046ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1048875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10494125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10505cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1051875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
105213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
105313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getCompositionType called without a valid HWC layer");
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
11009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
11019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
11029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
11041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
11051681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
11061681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
11071681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
11081681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
11091681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
11101681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
11111681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
11121681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
11131681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1114cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1115cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1116cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1117cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1118cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1119cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
11207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1121cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1123cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1124cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1125cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1129cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1130cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1131cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1132cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1143ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1144ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1145ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1146ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1147ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1148ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1149ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11505773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1153ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11545773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11555773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11565773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1157dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11585773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11595773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1160dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1161ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1162ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
116313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1167acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1168acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1169acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1170acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1171acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1172acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1173acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1174acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1175acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1176acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1177acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1178acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1179acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1180acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1181acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1182c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1183c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
11851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1186acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1189b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1190b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
11926c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1193f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
11943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1195acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1196acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1197acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1198acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1199acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1200acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1201acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1202acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1203acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1204acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1205acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1206acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1207b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1208b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1209b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1210b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1211b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1212acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1213acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1214ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1215acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1216acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1217acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1218acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12205cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
122213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1223ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12244125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1225a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1226a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1227a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1228db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1229a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1230db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1231a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1232a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1233a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12344125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1235a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1236a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1237231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1238231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1239231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1240231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1241231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1242231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12437a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12447a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1245a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12467a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12477a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12487a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1249b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
125013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
1251c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
125213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
125513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
125613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
126013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
126313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
126413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
126513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
126813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
126913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
127013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
127113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
127213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
127313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
127413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
127513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
127613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
127713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
127813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
127913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
128013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
128113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
12837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
12847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
12857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
12887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
12897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
12907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
12917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
12927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
12937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
12947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
12957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
12967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
12977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
12983bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
12993bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
13003bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1301cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1302cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1303cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1304cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1305cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1306cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1307cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
131605289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::popPendingState(State* stateToCommit) {
131705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    auto oldFlags = stateToCommit->flags;
131805289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    *stateToCommit = mPendingStates[0];
131905289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
132005289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            (stateToCommit->flags & stateToCommit->mask);
13217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
132505289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosbool Layer::applyPendingStates(State* stateToCommit) {
13267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
133405289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1339cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1340cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1341cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1342cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1343cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1344cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1345cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1346cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1347cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1348cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1349cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
13507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
135205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos                popPendingState(stateToCommit);
13537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
13567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
13577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1358792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1359792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
13607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
136205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos            popPendingState(stateToCommit);
13637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
13727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
13757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
13767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1379cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
1380cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1381cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
1382cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (headFrameNumber >= point->getFrameNumber()) {
1383cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1384cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
13857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
138813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
13891c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13901c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
139205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    Layer::State c = getCurrentState();
139305289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    if (!applyPendingStates(&c)) {
13947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
13957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
14001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1401a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1402a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1403cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14049d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14056905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1406419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1407b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1408419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1409b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
1410c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                this, getName().string(), mCurrentTransform,
1411c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getEffectiveScalingMode(),
14121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1413b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1414b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1415b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1416b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1417b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1418b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1421b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1422b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1423b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1424b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1425b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1426b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1427b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14292a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14302a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1431bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1434cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
14350cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14360cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
14381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
14390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
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 {
146205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos        c.active = c.requested;
146313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
146613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
146713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
147113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
147213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
147313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
147513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
14763dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
14773dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
147813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
147913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
148013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
148205289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    commitTransaction(c);
148313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
148605289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballosvoid Layer::commitTransaction(const State& stateToCommit) {
148705289c2b78d21308a95ea6ef8f1d8f24359147cdPablo Ceballos    mDrawingState = stateToCommit;
1488a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
149013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
149113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
149213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
149313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
149413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
149513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
149613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
149713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
149813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
14993dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
150013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
150113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
150269663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
150369663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
150469663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
150569663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15063dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
150769663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    mCurrentState.active.transform.set(x, y);
150869663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
151013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
151113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
151413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
151713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
152013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
152113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
152213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
152313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
152413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
152513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
152613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
15277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
152813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
152913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
153013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
15329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
15339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
153413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
15359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
153613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
153713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
153813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
153913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
15407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
154113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
154213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
154313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
154413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
154513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
15463dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
154713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
15487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
154913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
155013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
155113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
15532ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
15547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
155513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
155613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
155713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
155913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
156013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
156113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
156213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
156313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
15647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
156613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
156713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
156813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
156913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
1570b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
157113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
157213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
1573b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop = crop;
15747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
157513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
157613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
157713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1578acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1579b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1580acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1581acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1582b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1583acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1584acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1585acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1586acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
158713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1588c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carrbool Layer::setOverrideScalingMode(int32_t scalingMode) {
1589c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (scalingMode == mOverrideScalingMode)
1590c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        return false;
1591c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    mOverrideScalingMode = scalingMode;
1592c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return true;
1593c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1594c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
1595c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carruint32_t Layer::getEffectiveScalingMode() const {
1596c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    if (mOverrideScalingMode >= 0) {
1597c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr      return mOverrideScalingMode;
1598c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    }
1599c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr    return mCurrentScalingMode;
1600c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr}
1601c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr
160213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
160313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
160413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
160513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
160613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
16077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
160813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
160913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1610a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1611a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
16127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
16137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
16147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
16157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
16167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
16177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
16187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
16197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1620792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1621792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
16227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
16237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
16247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1625ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1626ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1627ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1628ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1629ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1630ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1631ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1632ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1633ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1634ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1635ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1636ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16416b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1642ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1643d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1644d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1645d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
16466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
16470eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
16480eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
16490eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
16500eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
16516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
16526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
16530eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16540eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
16550eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
16560eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
16570eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
16580eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
16590eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16600eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
16610eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
16626b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
16636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
16644d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
16654d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1666ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
166799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
166899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1669d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1670d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1671bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
167282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
167382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1674bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1675789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
167682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
167782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
167882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
167982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
168082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
168182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
168282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1683d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
16849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
16869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
168782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
16889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1689789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
169082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
169182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
169282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
169382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
169482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
169582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
169682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
169782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
169882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1699d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1700d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1701d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1702d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
17039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
17059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
17069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
17079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
17089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1709da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
171013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
17119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
17129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
17139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
171513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1716afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
17179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1718da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1719da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
17204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
17231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1724399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1725399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1726399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
172712e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
172812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
172912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
173012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
17315bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
17325bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
17335bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
17343dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1735399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1736399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
17374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1738ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mQueuedFrames > 0 || mAutoRefresh) {
173999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
174099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
174199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
174299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
174399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
174499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
17454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
17464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
174799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
174899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1749351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
17504125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
17514125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1752351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1753db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1754bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
17552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
17562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
17572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
17581681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
1759b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            const char* name;
1760c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            int32_t overrideScalingMode;
1761b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
17622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
1763b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                    bool& recomputeVisibleRegions, bool stickySet,
1764c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                    const char* name,
1765c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                    int32_t overrideScalingMode)
17662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
17671681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
1768b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                  stickyTransformSet(stickySet),
1769c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                  name(name),
1770c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                  overrideScalingMode(overrideScalingMode) {
17712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
17722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
177411611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
17752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
17762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
17772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
17802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
17812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
17832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
17842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
17852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
17862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1788c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                int actualScalingMode = overrideScalingMode >= 0 ?
1789c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                        overrideScalingMode : item.mScalingMode;
1790c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
17912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
17922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
17942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
17952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
17962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
17972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
17982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
17992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
18002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
18012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
18032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
18042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
18052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
18062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
18072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
18082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
18092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
18112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
18122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
18132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
1815b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
18162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1817b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "            requested={ wh={%4u,%4u} }}\n",
1818b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            name,
18196905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
18202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
1821b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.left,
1822b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.top,
1823b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.right,
1824b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.bottom,
1825b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getWidth(),
1826b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getHeight(),
1827b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.requested.w, front.requested.h);
18282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18301681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
18312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
18322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
18334824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
1834b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                        ALOGE("[%s] rejecting buffer: "
1835b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1836b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                name, bufWidth, bufHeight, front.active.w, front.active.h);
18372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
18382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
18392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
18412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
18422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
18432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
18442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
18452ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
18462ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
18472ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
18486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
18506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
18516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
18526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
18536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
18546c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
18556c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
18566c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18576c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
18582ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
18592ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
18602ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
18612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
18622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
18632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
18642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18651681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1866c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                getProducerStickyTransform() != 0, mName.string(),
1867c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr                mOverrideScalingMode);
18682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1870cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1871cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1872cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1873cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1874cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1875cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1876cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
18777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1878cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1879cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1880cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
18817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
18827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1883cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
18847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1885cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1886cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1887cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1888cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1889cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1890cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1891cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1892cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1893cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1894cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1895cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
18967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1897a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1898a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1899cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
1900cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
1901cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
1902cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1903cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1904063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1905063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
19063559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in shared
1907063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1908063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
190941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1910ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
1911cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
19121585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
19131585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
19141585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
19151585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
19161585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1917ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1918ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1919ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1920063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1921063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1922063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1923063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1924063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1925ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
192665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
192765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
192865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
192965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
193065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1931063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
193265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
193365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
193465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
193565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
193665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
193765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
193865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
193965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
194065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
194165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
194265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
194365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
19441585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
19451585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1946063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1947063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1948ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1949ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1951ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1952ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1953ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1954ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1955ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1956ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1957ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1958ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
19606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
19616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1962ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
19641585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1965063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1966ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                || mAutoRefresh) {
19671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
19681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
19691585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
19701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1971a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1972a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1974a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1975d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1976351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1977bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1978e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1979e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
19804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1981e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1982da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
19834824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1984702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1985e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
19862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
19872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1988ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
19892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1990702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1991bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1992bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1993bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1994702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1995702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1996702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1997702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1998702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1999702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
2000702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
2001ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
2002702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2003702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2004702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
2005e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
2006e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
2007702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
2008702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
2009ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
2010702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
2011702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2012702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2013702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
20144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
2015702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
2016702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
2017702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
2018cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2019cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2020cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
2021cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
2022cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
2023cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
2024cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
2025cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
2026cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
2027cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
2028cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
2029cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
2030cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2031cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
2032cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2033cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2034cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2035cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
2036cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
2037cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2038cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2039cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2040cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2041cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
20424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
20431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
20441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
20454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
20463dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        outDirtyRegion = (s.active.transform.transform(dirtyRegion));
2047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
205113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
205213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
205313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
205413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
205513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
205613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
205713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
205803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
205903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
206003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
206113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
206213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
206313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
206413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
206513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
206613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
206713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
206813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
206913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
207013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
207113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
207213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
207313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
207413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
207513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
207613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
207713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
207813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
207913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
208013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
208113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
208213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
208313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20843e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
20851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
20861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
208713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
208974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
209013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
209113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
20923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
209313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20942ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
209513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2096ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
209713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
209813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
209974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2100acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2101acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
210213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
21039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
21049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
210613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
21079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
210813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
21093dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2110b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2111b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2112b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2113b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
21144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
211513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
21163dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
21173dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
211813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
21191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2120a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2121a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
21221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
21231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
21241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
21251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
21271b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
212874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
21291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2130ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
21316905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2132a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
21336905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
21341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
213674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
2137bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2138d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2139d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
2140d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2141d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
214282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
214382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2144d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2145d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
214625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
214725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
21486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
21496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
21506547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
21516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2152d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2153d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2154d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2155d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
215640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
215740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        bool* outIsGlesComposition, nsecs_t* outPostedTime,
215840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
215940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outName = mName;
216040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
216140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
216240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifdef USE_HWC2
216340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
216440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
216540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            HWC2::Composition::Client : true;
216640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#else
216740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mIsGlesComposition;
216840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
216940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
217040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
217140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
217240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
217313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
217413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
217513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
217613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
217713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
2178b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
2179b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
218013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
218113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
218213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
2183a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
2184a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
21863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
21893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
21903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
21933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
21943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2195