Layer.cpp revision 69663fb0de2f112f525c4dcd7e2f7e0c879daaa4
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),
78a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
79cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber(0),
804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
8182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
8313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
845cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
8540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifndef USE_HWC2
8640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        mIsGlesComposition(false),
8740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
8813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
9003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
91a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
92a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
93a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
94a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
9565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9604839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
97ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        mAutoRefresh(false)
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
1019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
10549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1094125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1104125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1114125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
112231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
113231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1223dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.active.transform.set(0, 0);
123b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop.makeInvalid();
124b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop.makeInvalid();
1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
148e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
149e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
151bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
152b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
153b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
154b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
155b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
156b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
157bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
158399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
160b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1617f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1627f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1637f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
16419e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
165303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1666905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
169b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
17096f0819f81293076e652792794a961543e6750d7Mathias Agopian
1714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
1728ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos  sp<Client> c(mClientRef.promote());
1738ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    if (c != 0) {
1748ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos        c->detachLayer(this);
1758ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos    }
1768ea4e7b878540647bb7ceeaa1d62d50cd458d9c6Pablo Ceballos
177cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
178cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
179cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
180921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1816547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
18296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
18396f0819f81293076e652792794a961543e6750d7Mathias Agopian
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
1929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
196c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
20013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
2039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2056b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
2066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
2076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
2086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
209a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
210a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
211a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
212a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
213a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
214a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
215a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
222a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
223a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
224a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
226ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
227a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
228a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
229a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
23399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
234579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
235579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2366b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
239a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
247a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
248a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItems.editItemAt(0) = item;
2547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
261399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
262399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
263399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
264399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
265399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
266399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
267399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2696710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
272bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
27348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
274cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
3107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
3117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
3127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
3137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
3147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
3157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
3167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
3177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
336b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
337b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
344a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
345a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
346a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
347f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
348f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
349a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
350f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
351a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
352a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
353a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
354f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
355a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
357f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
358f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
359f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
360f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
361f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
362f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
363f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
364f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
365f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
366f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
367f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
368f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
369f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
370f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
37113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3766c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3776c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
379b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
380b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
381b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
38213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3836c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3846c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3876b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3906b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
392b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    // the crop is the area of the window that gets cropped, but not
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
39513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
39713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3986b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3996b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
4006b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
4016b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
4020e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4030e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
404b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
405b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        activeCrop = s.crop;
4060e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
4070e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4083dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.transform(activeCrop);
409acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
410acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
411acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
412b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
413b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
414acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
415acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
416acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
4173dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    activeCrop = s.active.transform.inverse().transform(activeCrop);
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
41928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
42028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
42128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
42228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
42328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
42428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
425acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        activeCrop.clear();
427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
429f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
430f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
431f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
432acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // Transform the window crop to match the buffer coordinate system,
433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // which means using the inverse of the current transform set on the
434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // SurfaceFlingerConsumer.
435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    uint32_t invTransform = mCurrentTransform;
436acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
437acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        /*
438acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         * the code below applies the display's inverse transform to the buffer
439acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos         */
440acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        uint32_t invTransformOrient = hw->getOrientationTransform();
441acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // calculate the inverse transform
442acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
443acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
444acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
445acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            // If the transform has been rotated the axis of flip has been swapped
446acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            // so we need to swap which flip operations we are performing
4477b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4487b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
449acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (is_h_flipped != is_v_flipped) {
4507b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4517b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4527b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
45313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
454acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // and apply to the current transform
455acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
456acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
457acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
458acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winWidth = s.active.w;
459acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    int winHeight = s.active.h;
460acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
461acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // If the activeCrop has been rotate the ends are rotated but not
462acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // the space itself so when transforming ends back we can't rely on
463acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // a modification of the axes of rotation. To account for this we
464acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // need to reorient the inverse rotation in terms of the current
465acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        // axes of rotation.
466acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
467acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
468acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (is_h_flipped == is_v_flipped) {
469acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
470acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
471acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
472acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winWidth = s.active.h;
473acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        winHeight = s.active.w;
474acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
475acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Rect winCrop = activeCrop.transform(
476acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            invTransform, s.active.w, s.active.h);
47713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
478acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    // below, crop is intersected with winCrop expressed in crop's coordinate space
479acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float xScale = crop.getWidth()  / float(winWidth);
480acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float yScale = crop.getHeight() / float(winHeight);
48113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
482acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetL = winCrop.left                 * xScale;
483acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetT = winCrop.top                  * yScale;
484acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetR = (winWidth - winCrop.right )  * xScale;
485acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    float insetB = (winHeight - winCrop.bottom) * yScale;
486acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
487acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.left   += insetL;
488acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.top    += insetT;
489acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.right  -= insetR;
490acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    crop.bottom -= insetB;
49113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
49313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
4984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
5004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
502a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
50713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
509a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
5103e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5203e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
521a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
522dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
523dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
524dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
526dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5394125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
54013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
54113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
54213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
54313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
54513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
54713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5486c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
549b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
550b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        Rect activeCrop(s.crop);
5513dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.transform(activeCrop);
5529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
553acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
5549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
555acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
557acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
558acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5593dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        activeCrop = s.active.transform.inverse().transform(activeCrop);
56028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
56128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
56228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
56328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
56428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
56528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
566acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
567acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            activeCrop.clear();
568acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
5696c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5706c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5716c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5776c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5783dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
579b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
580b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if(!frame.intersect(s.finalCrop, &frame)) {
581acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            frame.clear();
582acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
583acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
585acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(displayDevice->getViewport(), &frame)) {
586acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
587acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.top, transformedFrame.right,
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.bottom, to_string(error).c_str(),
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.left, sourceCrop.top, sourceCrop.right,
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.bottom, to_string(error).c_str(),
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
6069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
6079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
6089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
6119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
6129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
6139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
615acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!frame.intersect(hw->getViewport(), &frame)) {
616acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        frame.clear();
617acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
61813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
61913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
62013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
6219f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
6229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6239f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
62429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
62529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
62629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
62729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
62829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
62929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
63029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
63129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
63229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
6333dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Transform transform(tr * s.active.transform * bufferOrientation);
634c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
635c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
636c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
638c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
6399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        uint32_t invTransform = displayDevice->getOrientationTransform();
6419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
642c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
6439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6441440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
645c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
646c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
647c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
648c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
6491440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
6501440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
6511440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
6521440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
6531440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
6541440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
6551440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
6561440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
657c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
658c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6591440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
660c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
66129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
66229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
66313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
67613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
67713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
6783e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
679a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
68013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
681a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
683a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
684a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
7039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
7159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
7179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto compositionType = HWC2::Composition::Invalid;
7209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        compositionType = HWC2::Composition::Sideband;
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
7269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            return;
7289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
7319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            compositionType = HWC2::Composition::Client;
7329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
7339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
7359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        to_string(error).c_str(), static_cast<int32_t>(error));
7369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
7399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (mPotentialCursor) {
7409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                compositionType = HWC2::Composition::Cursor;
7419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
7449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    acquireFence);
7459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        mActiveBuffer->handle, to_string(error).c_str(),
7489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        static_cast<int32_t>(error));
7499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // If it's not a cursor, default to device composition
7529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers[hwcId].forceClientComposition) {
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Forcing Client composition", mName.string());
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (compositionType != HWC2::Composition::Invalid) {
7599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting %s composition", mName.string(),
7609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(compositionType).c_str());
7619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, compositionType);
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
7684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
769d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
77113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
77513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
778db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
77940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
780ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
781399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
782399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
783399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
784399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
785399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
786399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
787399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
788c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
7929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
8009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
801dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
8029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
8039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
8049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
805b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
806b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
8079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
8089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
8099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
810baf416d62eec3045ba4fd61f2df60f3e82f12d52Dan Stoza    Rect frame(s.active.transform.transform(bounds));
8119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
812b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
813b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
814acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
8159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
8169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
8179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
8189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
8199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
8209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
8219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
8229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
8239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
8249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
8259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
826c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
827d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
828c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
829d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
830d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
831d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
832d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
83303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
834bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8351df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
836c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
837dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
838dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
839dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
840dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
841dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
842c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
843c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
844c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
84503414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
84603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
84703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
84803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
84903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
85003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
85103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
85203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
85303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
854b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
855b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
85603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
85703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
85803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
8593dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    Rect frame(s.active.transform.transform(bounds));
86003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
861b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
862b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        frame.intersect(s.finalCrop, &frame);
863acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
86403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
86503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
86603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
8679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
86803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
86913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
874c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
877c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
878c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
882c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
883c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
884c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
885c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
886c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
887c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8891c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8901c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
891a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
893179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
894179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
895179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
896179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
897179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
898179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
899179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
900179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
901179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
902f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
903f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
904179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
905179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
90713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
908179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
9094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
910179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
911179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
912179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
913179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
9141b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
915179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
918a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
91997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
92097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
921bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
922bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
92397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
924dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
925dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
926dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
927dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
928dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
929dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
930875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
931875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
932dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
933cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
934eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
935cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
936cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
937cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
938bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
939bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
940cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
941c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
942c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
943c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
944c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
945c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
946c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
947c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
948c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
949c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
950c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
951c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
952c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
953c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
954c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
955c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
956c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
957c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
958c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
959c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
960c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
961c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
962c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
963c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
964c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
965c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
966c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
967c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
968c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
969cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
97049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
97149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
97249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
97349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
97449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
975a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
976875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
977a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
978c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
979875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
983c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
984c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
985c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
98719733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
988c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
98919733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
99019733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
998c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
999c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
10001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1002c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
1013c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
1018acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    Rect win(computeBounds());
1019acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1020b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1021acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.transform(win);
1022b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        if (!win.intersect(s.finalCrop, &win)) {
1023acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1024acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1025acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        win = s.active.transform.inverse().transform(win);
1026acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (!win.intersect(computeBounds(), &win)) {
1027acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            win.clear();
1028acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
1029acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
10323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
10333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
10343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1036875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
1037875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
1038ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1039ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
1040ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
1041ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
1042ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1044875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10454125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10465cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1047875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getCompositionType called without a valid HWC layer");
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
10969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
10989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10991681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
11001681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
11011681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
11021681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
11031681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
11041681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
11051681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
11061681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
11071681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
11081681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
11091681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1110cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1111cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1112cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1113cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1114cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1115cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
11167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1117cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
11187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1119cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1120cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1121cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1122cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1123cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
11247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1125cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1126cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1127cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1128cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
11297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
11307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
113213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
113413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1139ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1140ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1141ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1142ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1143ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1144ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1145ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11465773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1147a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1149ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11505773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11515773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11525773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1153dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11545773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11555773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1156dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1157ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1158ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
115913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
116113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1163acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosstatic void boundPoint(vec2* point, const Rect& crop) {
1164acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x < crop.left) {
1165acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.left;
1166acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1167acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->x > crop.right) {
1168acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->x = crop.right;
1169acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1170acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y < crop.top) {
1171acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.top;
1172acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1173acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (point->y > crop.bottom) {
1174acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        point->y = crop.bottom;
1175acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1176acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
1177acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1178c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1179c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
11811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1182acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    const Transform tr(hw->getTransform());
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
1185b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.crop.isEmpty()) {
1186b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        win.intersect(s.crop, &win);
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
11886c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1189f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
11903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1191acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lt = vec2(win.left, win.top);
1192acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 lb = vec2(win.left, win.bottom);
1193acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rb = vec2(win.right, win.bottom);
1194acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    vec2 rt = vec2(win.right, win.top);
1195acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1196acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    if (!useIdentityTransform) {
1197acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lt = s.active.transform.transform(lt);
1198acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        lb = s.active.transform.transform(lb);
1199acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rb = s.active.transform.transform(rb);
1200acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        rt = s.active.transform.transform(rt);
1201acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1202acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1203b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (!s.finalCrop.isEmpty()) {
1204b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lt, s.finalCrop);
1205b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&lb, s.finalCrop);
1206b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rb, s.finalCrop);
1207b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr        boundPoint(&rt, s.finalCrop);
1208acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    }
1209acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos
1210ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1211acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[0] = tr.transform(lt);
1212acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[1] = tr.transform(lb);
1213acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[2] = tr.transform(rb);
1214acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    position[3] = tr.transform(rt);
12153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
12165cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
121713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
121813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1219ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
12204125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1221a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1222a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1223a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1224db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1226db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1227a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1228a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1229a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
12304125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1231a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1232a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1233231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1234231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1235231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1236231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1237231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1238231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
12397a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
12407a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1241a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
12427a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
12437a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
12447a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1245b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
124613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
124713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
124813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
124913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
125113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
125213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
125513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
125613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
125713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
125813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
125913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
126013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
126113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
126413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
126513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
126613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
126713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
126813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
126913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
127013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
127113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
127213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
127313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
127413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
127513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
127613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
127713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
12797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
12807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
12817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
12847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
12857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
12867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
12877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
12887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
12897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
12907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
12917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
12927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
12937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
12943bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
12953bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
12963bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1297cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1298cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1299cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1300cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1301cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1302cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1303cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
13047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
13077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
13107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::popPendingState() {
13137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto oldFlags = mCurrentState.flags;
13147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState = mPendingStates[0];
1315cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
13167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            (mCurrentState.flags & mCurrentState.mask);
13177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
13197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozabool Layer::applyPendingStates() {
13227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
13237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
13247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
13257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
13267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
13277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
13287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
13297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
13307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
13317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
13337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1335cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1336cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1337cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1338cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1339cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1340cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1341cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1342cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1343cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1344cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1345cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
13467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
13477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
13487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
13497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
13507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
13527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
13537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1354792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1355792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
13567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
13577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
13587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            popPendingState();
13597dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
13607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
13617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
13647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
13657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
13667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
13677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
13687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
13717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
13727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1375cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
1376cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1377cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
1378cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (headFrameNumber >= point->getFrameNumber()) {
1379cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1380cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
13817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
138413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
13851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13861c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
13887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!applyPendingStates()) {
13897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
13907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
13931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
13961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1399cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
14009d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
14016905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1402419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1403b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n"
1404419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1405b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                "            requested={ wh={%4u,%4u} }}\n",
14061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
14071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
1408b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.left,
1409b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.top,
1410b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.right,
1411b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.bottom,
1412b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getWidth(),
1413b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                c.crop.getHeight(),
14141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
14151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
1416b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.left,
1417b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.top,
1418b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.right,
1419b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.bottom,
1420b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getWidth(),
1421b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.crop.getHeight(),
1422b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                s.requested.w, s.requested.h);
1423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
14242a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
14252a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1426bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
14271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1429cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
14300cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
14310cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
14331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
14340cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14359e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
143613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
14370cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
14380cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
14390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
14400cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
14410cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
14420cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
14430cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
14449e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
14459e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
14469e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
14479e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
14480cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
14490cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
14500cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
14510cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
14520cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
145313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
145413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
145513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
145613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
14571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
14581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
145913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
146213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
146313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
146413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
146713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
147013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
147113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
14723dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        const uint8_t type = c.active.transform.getType();
14733dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        mNeedsFiltering = (!c.active.transform.preserveRects() ||
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
147513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
147613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
147713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
147813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
147913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
148213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
148313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1484a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1485a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
148613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
148713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
148813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
148913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
149013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
149113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
149213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
149313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
149413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
14953dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
149613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
149713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
149869663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
149969663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // We update the requested and active position simultaneously because
150069663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // we want to apply the position portion of the transform matrix immediately,
150169663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
15023dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(x, y);
150369663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr    mCurrentState.active.transform.set(x, y);
150469663fb0de2f112f525c4dcd7e2f7e0c879daaa4Robert Carr
15057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
150613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
150713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
150813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
150913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
151013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
151113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
151313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
15147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
151713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
152013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
152113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
152213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
15237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
152413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
152513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
152613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
15289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
15299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
153013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
15319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
153213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
153313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
153413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
153513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
15367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
153713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
153813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
153913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
154013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
154113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
15423dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr    mCurrentState.requested.transform.set(
154313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
15447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
154513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
154613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
154713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
154813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
15492ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
15507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
155113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
155213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
155313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
155413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
155513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
155613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
155713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
155813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
155913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
15607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
15617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
156213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
156313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
156413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
156513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
1566b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.crop == crop)
156713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
156813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
1569b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.crop = crop;
15707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
157113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
157213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
157313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1574acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballosbool Layer::setFinalCrop(const Rect& crop) {
1575b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    if (mCurrentState.finalCrop == crop)
1576acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        return false;
1577acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.sequence++;
1578b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr    mCurrentState.finalCrop = crop;
1579acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    mCurrentState.modified = true;
1580acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    setTransactionFlags(eTransactionNeeded);
1581acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos    return true;
1582acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos}
158313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
158413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
158513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
158613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
158713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
158813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
15897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
159013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
159113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1592a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1593a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
15947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
15957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
15967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
15977dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
15987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
15997dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
16007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
16017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1602792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1603792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
16047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
16057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
16067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1607ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1608ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1609ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1610ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1611ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1612ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1613ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1614ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1615ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1616ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1617ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1618ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16236b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1624ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1625d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1626d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1627d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
16286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
16290eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
16300eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
16310eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
16320eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
16336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
16346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
16350eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16360eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
16370eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
16380eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
16390eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
16400eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
16410eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
16420eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
16430eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
16446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
16456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
16464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
16474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1648ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
164999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
165099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1651d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1652d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1653bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
165482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
165582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1656bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1657789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
165882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
165982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
166082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
166182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
166282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
166382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
166482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1665d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
16669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
16689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
166982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
16709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1671789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
167282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
167382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
167482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
167582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
167682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
167782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
167882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
167982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
168082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1681d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1682d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1683d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1684d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
16859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
16879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
16889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
16899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
16909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1691da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
169213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
16939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
16959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
16969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
169713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1698afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
16999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1700da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1701da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
17024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17041c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
17051c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1706399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1707399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1708399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
170912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
171012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
171112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
171212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
17135bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
17145bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
17155bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
17163dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
1717399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1718399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
17194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1720ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mQueuedFrames > 0 || mAutoRefresh) {
172199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
172299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
172399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
172499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
172599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
172699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
17274d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
17284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
172999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
173099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1731351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
17324125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
17334125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1734351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1735db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1736bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
17372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
17382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
17392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
17401681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
1741b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            const char* name;
1742b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr
17432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
1744b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                    bool& recomputeVisibleRegions, bool stickySet,
1745b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                    const char* name)
17462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
17471681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
1748b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                  stickyTransformSet(stickySet),
1749b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                  name(name) {
17502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
17512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
175311611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
17542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
17552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
17562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
17592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
17602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
17622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
17632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
17642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
17652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
17682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
17692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
17712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
17722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
17732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
17742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
17752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
17762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
17772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
17782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
17802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
17812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
17822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
17832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
17842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
17852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
17862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
17882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
17892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
17902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
1792b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
17932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1794b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            "            requested={ wh={%4u,%4u} }}\n",
1795b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            name,
17966905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
17972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
1798b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.left,
1799b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.top,
1800b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.right,
1801b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.bottom,
1802b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getWidth(),
1803b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.crop.getHeight(),
1804b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                            front.requested.w, front.requested.h);
18052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18071681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
18082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
18092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
18104824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
1811b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                        ALOGE("[%s] rejecting buffer: "
1812b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1813b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                                name, bufWidth, bufHeight, front.active.w, front.active.h);
18142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
18152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
18162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
18172ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
18182ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
18192ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
18202ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
18212ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
18222ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
18232ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
18242ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
18256c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18266c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
18276c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
18286c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
18296c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
18306c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
18316c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
18326c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
18336c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
18346c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
18352ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
18362ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
18372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
18382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
18392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
18402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
18412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18421681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1843b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr                getProducerStickyTransform() != 0, mName.string());
18442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
18457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1846cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1847cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1848cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1849cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1850cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1851cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1852cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
18537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1854cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1855cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1856cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
18577dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
18587dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1859cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
18607dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1861cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1862cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1863cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1864cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1865cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1866cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1867cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1868cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1869cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1870cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1871cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
18727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1873a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1874a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1875cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
1876cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
1877cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
1878cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1879cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1880063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1881063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
1882063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in single
1883063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1884063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
188541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1886ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
1887cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
18881585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
18891585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
18901585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
18911585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
18921585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1893ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1894ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1895ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1896063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1897063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1898063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1899063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1900063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1901ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
190265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
190365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
190465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
190565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
190665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1907063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
190865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
190965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
191065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
191165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
191265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
191365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
191465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
191565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
191665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
191765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
191865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
191965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
19201585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
19211585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1922063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1923063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1924ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1925ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1927ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1928ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1929ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1930ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1931ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1932ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1933ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1934ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
19366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
19376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1938ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
19391585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
19401585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1941063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1942ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                || mAutoRefresh) {
19431585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
19441585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
19451585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
19461585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1947a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1948a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
19494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1950a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1951d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1952351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1953bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1954e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1955e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
19564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1957e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1958da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
19594824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1960702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1961e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
19622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
19632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1964ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
19652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1966702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1967bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1968bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1969bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1970702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1971702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1972702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1973702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1974702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1975702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1976702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1977ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1978702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1979702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1980702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1981e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1982e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1983702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1984702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1985ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1986702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1987702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1988702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1989702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
19904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1991702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1992702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1993702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1994cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1995cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1996cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
1997cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
1998cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
1999cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
2000cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
2001cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
2002cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
2003cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
2004cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
2005cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
2006cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2007cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
2008cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2009cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
2010cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2011cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
2012cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
2013cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
2014cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
2015cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
2016cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
2017cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
20184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
20191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
20201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
20214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
20223dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr        outDirtyRegion = (s.active.transform.transform(dirtyRegion));
2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
2025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
202813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
202913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
203013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
203113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
203213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
203313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
203403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
203503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
203603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
203713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
203813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
203913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
204013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
204113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
204213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
204313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
204413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
204513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
204613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
204713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
204813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
204913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
205013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
205113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
205213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
205313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
205413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
205513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
205613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
205713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
205813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
205913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
20611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
20621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
206313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
206574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
206613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
206713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
20683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
206913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
207113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
2072ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
207313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
207413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
207574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
2076acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2077acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
207813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
20799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
20809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
20819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
208213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
20839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
208413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
20853dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
2086b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.left, s.crop.top,
2087b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.crop.right, s.crop.bottom,
2088b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.left, s.finalCrop.top,
2089b5d3d2657bad1f012377dfacd354d3100a65768aRobert Carr            s.finalCrop.right, s.finalCrop.bottom,
20904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
209113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
20923dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[0][0], s.active.transform[0][1],
20933dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            s.active.transform[1][0], s.active.transform[1][1],
209413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
20951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2096a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2097a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
20981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
20991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
21001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
21011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
21031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
210474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
21051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2106ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
21076905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2108a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
21096905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
21101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2111bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
211274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
2113bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2114d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2115d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
2116d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2117d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
211882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
211982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2120d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2121d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
212225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
212325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
21246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
21256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
21266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
21276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2128d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2129d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2130d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2131d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
213240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
213340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        bool* outIsGlesComposition, nsecs_t* outPostedTime,
213440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos        sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
213540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outName = mName;
213640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
213740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
213840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#ifdef USE_HWC2
213940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
214040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
214140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            HWC2::Composition::Client : true;
214240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#else
214340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outIsGlesComposition = mIsGlesComposition;
214440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos#endif
214540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
214640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
214740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
214840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos}
214913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
215013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
215113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
215213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
215313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
2154b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
2155b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
215613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
215713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
215813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
2159a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
2160a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
21623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
21653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
21663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
21693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
21703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2171