Layer.cpp revision 9e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9
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),
8513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
88a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mPotentialCursor(false),
89a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemLock(),
90a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition(),
91a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItems(),
9265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        mLastFrameNumberReceived(0),
9304839abb2dbfe7afe57ccc91902870aab52d30b8Pablo Ceballos        mUpdateTexImageFailed(false),
94ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        mAutoRefresh(false)
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Creating Layer %s", name.string());
989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
100a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
1013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
10249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
1064125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
1074125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
1084125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
109231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    if (flags & ISurfaceComposerClient::eSecure)
110231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        layerFlags |= layer_state_t::eLayerSecure;
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mCurrentState.alpha = 1.0f;
1239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& hwc = flinger->getHwComposer();
1379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
1406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
144e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
145e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
147bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
148b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
149b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
150b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
151b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
152b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
153bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
154399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
156b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1577f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1587f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
1597f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
16019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
161303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1626905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
165b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian
1674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
168cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mRemoteSyncPoints) {
169cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        point->setTransactionApplied();
170cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    }
171921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
17396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
17496f0819f81293076e652792794a961543e6750d7Mathias Agopian
17513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
17613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
17813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
1809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
1819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.empty()) {
1829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
1839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
1859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
187c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
19113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1966b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1986b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
200a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
201a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Reset the frame number tracker when we receive the first buffer after
202a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // a frame number reset
203a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        if (item.mFrameNumber == 1) {
204a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            mLastFrameNumberReceived = 0;
205a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
206a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
207a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Ensure that callbacks are handled in order
208a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
209a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
210a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                    ms2ns(500));
211a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            if (result != NO_ERROR) {
212a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
213a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza            }
214a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
215a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
217ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        android_atomic_inc(&mQueuedFrames);
218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
219a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        // Wake up any pending callbacks
220a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
221a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        mQueueItemCondition.broadcast();
2226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
22499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
225579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
226579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
2276b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
2287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    { // Autolock scope
2297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Mutex::Autolock lock(mQueueItemLock);
230a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Ensure that callbacks are handled in order
2327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
2337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
2347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    ms2ns(500));
2357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (result != NO_ERROR) {
2367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] Timed out waiting on callback", mName.string());
2377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
238a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
239a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
2407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mQueueItems.empty()) {
2417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("Can't replace a frame on an empty queue");
2427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            return;
2437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItems.editItemAt(0) = item;
2457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
2467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake up any pending callbacks
2477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mLastFrameNumberReceived = item.mFrameNumber;
2487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mQueueItemCondition.broadcast();
2496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
2506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
2516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
252399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
253399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
254399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
255399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
256399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
257399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
258399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
2596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
2606710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
2616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
26213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
263e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    sp<Client> c(mClientRef.promote());
264e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    if (c != 0) {
265e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos        c->detachLayer(this);
266e338df1c2ff4ed2cd575a0e3193ef77c9cd9cb72Pablo Ceballos    }
267bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
26848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
269cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
28713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza/*
3057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * The layer handle is just a BBinder object passed to the client
3067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * (remote process) -- we don't keep any reference on our side such that
3077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * the dtor is called when the remote side let go of its reference.
3087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza *
3097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
3107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza * this layer when the handle is destroyed.
3117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza */
3127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozaclass Layer::Handle : public BBinder, public LayerCleaner {
3137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    public:
3147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
3157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            : LayerCleaner(flinger, layer), owner(layer) {}
3167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        wp<Layer> owner;
3187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza};
3197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
3204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
3214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
3224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
3244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
3254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
3274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
3284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
330582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
331b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
332b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
33713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
33813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
339a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
340a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
341a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
342f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
343f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
344a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
345f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
346a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
347a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
348a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
349f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
350a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
3514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
352f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
353f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
354f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
355f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
356f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
357f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
358f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
359f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
360f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
361f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
362f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
363f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
364f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
365f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
36613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
3671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
3686c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
3696c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
3706c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
3716c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3776c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3786c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
38013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3816b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
38213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
38313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3846b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3926b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3936b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3946b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3956b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3960e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3970e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3980e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3990e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
4000e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
4010e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
4020e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
40313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
40413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
40728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
40828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
40928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
41028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
41128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
41213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
414f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
415f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
416f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
41713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
41813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
42013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
4216b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
422f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
423f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
424f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
425f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
426f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
427f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
428f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
429f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
430f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4311440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
4321440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
4331440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4341440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4351440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
4361440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4371440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
4381440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
439f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
440f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
441f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
442f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
443f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
44413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
44513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
4477b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
4487b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
4497b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
4507b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
4517b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
4527b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4537b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4547b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
4557b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4567b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4577b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
45813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
46013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
462f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
46313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4646b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
4656b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
4666b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
468f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
469f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
470f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
471f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
47213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
47313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
47413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
47513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
47613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
47713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
47813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
47913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
48013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
4839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
4844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
488a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
49313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
495a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4963e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcInfo.forceClientComposition = false;
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (isSecure() && !displayDevice->isSecure()) {
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5063e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
507a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
508dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
509dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
510dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
512dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
5141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isOpaque(s) || s.alpha != 1.0f) {
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto blendMode = mPremultipliedAlpha ?
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setBlendMode(blendMode);
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %s (%d)", mName.string(), to_string(blendMode).c_str(),
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5254125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
52613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
52813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
52913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
53113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
53213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
53313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
5346c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
5356c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
5366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
5376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
5416c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
5429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
5436c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
54428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
54528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
54628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
54728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
54828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
54928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
55028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
5516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
5526c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
5536c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
5546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
5556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
5566c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
5576c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
5586c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
5596c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
5606c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
5619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
5629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
5639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr(displayDevice->getTransform());
5649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect transformedFrame = tr.transform(frame);
5659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setDisplayFrame(transformedFrame);
5669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
5679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
5689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.top, transformedFrame.right,
5699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            transformedFrame.bottom, to_string(error).c_str(),
5709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    FloatRect sourceCrop = computeCrop(displayDevice);
5739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSourceCrop(sourceCrop);
5749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
5759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
5769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.left, sourceCrop.top, sourceCrop.right,
5779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sourceCrop.bottom, to_string(error).c_str(),
5789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setPlaneAlpha(s.alpha);
5819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
5829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
5839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setZOrder(s.z);
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mName.string(), s.z, to_string(error).c_str(),
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
59013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
59113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
59213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
5949f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
5969f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
59729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
59829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
59929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
60029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
60129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
60229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
60329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
60429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
60529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
606c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
607c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
608c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
609c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
610c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
611c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
6129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        uint32_t invTransform = displayDevice->getOrientationTransform();
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
615c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
6169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6171440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
618c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
619c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
620c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
621c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
6221440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
6231440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
6241440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
6251440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
6261440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
6271440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
6281440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
6291440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
630c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
631c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
6321440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
633c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
63429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
63529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
6379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (orientation & Transform::ROT_INVALID) {
6399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // we can only handle simple transformation
6409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.forceClientComposition = true;
6419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
6429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto transform = static_cast<HWC2::Transform>(orientation);
6439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setTransform(transform);
6449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
6459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", mName.string(), to_string(transform).c_str(),
6469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
64913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
6513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
652a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
65313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
654a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
6559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
656a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
657a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::forceClientComposition(int32_t hwcId) {
6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
6619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].forceClientComposition = true;
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply this display's projection's viewport to the visible region
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // before giving it to the HWC HAL.
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& tr = displayDevice->getTransform();
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& viewport = displayDevice->getViewport();
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Region visible = tr.transform(visibleRegion.intersect(viewport));
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = mHwcLayers[hwcId].layer;
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcLayer->setVisibleRegion(visible);
6799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        visible.dump(LOG_TAG);
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        surfaceDamageRegion.dump(LOG_TAG);
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto compositionType = HWC2::Composition::Invalid;
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mSidebandStream.get()) {
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        compositionType = HWC2::Composition::Sideband;
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error != HWC2::Error::None) {
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mName.string(), mSidebandStream->handle(),
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
7009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            return;
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
7049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            compositionType = HWC2::Composition::Client;
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        to_string(error).c_str(), static_cast<int32_t>(error));
7099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (mPotentialCursor) {
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                compositionType = HWC2::Composition::Cursor;
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
7179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    acquireFence);
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (error != HWC2::Error::None) {
7199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
7209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        mActiveBuffer->handle, to_string(error).c_str(),
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        static_cast<int32_t>(error));
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                return;
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // If it's not a cursor, default to device composition
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
7269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers[hwcId].forceClientComposition) {
7299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Forcing Client composition", mName.string());
7309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Client);
7319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (compositionType != HWC2::Composition::Invalid) {
7329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting %s composition", mName.string(),
7339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(compositionType).c_str());
7349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, compositionType);
7359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
7369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("[%s] Requesting Device composition", mName.string());
7379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setCompositionType(hwcId, HWC2::Composition::Device);
7389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
7414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
742d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
74413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
751db4850c01ff02bf7f936aa427e1fa8af9abc8f22Dan Stoza    layer.setSurfaceDamage(surfaceDamageRegion);
752ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
753399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
754399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
755399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
756399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
757399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
758399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
759399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
760c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
7619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayDevice->getHwcDisplayId();
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0 ||
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
7689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // This gives us only the "orientation" component of the transform
7729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const State& s(getCurrentState());
773dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
7749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Apply the layer's transform, followed by the display's global transform
7759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Here we're guaranteed that the layer's transform preserves rects
7769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect win(s.active.w, s.active.h);
7779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!s.active.crop.isEmpty()) {
7789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        win.intersect(s.active.crop, &win);
7799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Subtract the transparent region and snap to the bounds
7819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect bounds = reduce(win, s.activeTransparentRegion);
7829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Rect frame(s.transform.transform(bounds));
7839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    frame.intersect(displayDevice->getViewport(), &frame);
7849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayTransform(displayDevice->getTransform());
7859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto position = displayTransform.transform(frame);
7869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
7889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top);
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "to (%d, %d): %s (%d)", mName.string(), position.left,
7919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            position.top, to_string(error).c_str(),
7929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            static_cast<int32_t>(error));
7939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
795c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
796d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
797c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
798d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
799d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
800d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
801d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
80203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
803bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
8041df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
805c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
806dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
807dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
808dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
809dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
810dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
811c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
812c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
813c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
81403414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
81503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
81603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
81703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
81803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
81903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
82003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
82103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
82203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
82303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
82403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
82503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
82603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
82703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
82803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
82903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
83003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
83103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
83203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
8339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
83403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
840c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
843c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
844c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
845c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
848c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
849c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
850c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
851c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
852c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
853c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8561c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
857a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
859179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
860179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
861179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
862179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
863179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
864179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
865179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
866179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
867179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
868f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
869f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
870179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
871179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
874179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
8754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
876179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
877179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
878179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
879179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
8801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
881179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
884a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
88597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
88697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
887bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
888bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
88997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
890dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
891dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
892dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
893dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
894dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
895dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
896875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
897875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
898dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
899cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
900eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
901cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
902cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
903cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
904bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
905bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
906cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
907c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
908c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
909c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
910c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
911c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
912c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
913c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
914c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
915c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
916c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
917c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
918c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
919c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
920c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
921c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
922c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
923c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
924c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
925c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
926c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
927c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
928c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
929c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
930c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
931c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
932c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
933c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
934c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
935cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
93649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
93749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
93849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
93949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
94049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
941a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
942875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
943a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
944c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
945875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
949c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
950c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
951c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
95213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
95319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
954c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
95519733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
95619733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
95713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
95913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
96313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
964c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
965c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
9661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
96713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
968c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
96913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
97013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
97113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
97313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
97413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
97513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
97613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
979c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
9873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
9883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
9893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
991875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
992875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
993ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
994ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
995ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
996ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
997ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
999875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
10004125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
10015cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
1002875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
10059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
10069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
10079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool callIntoHwc) {
10089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setCompositionType called without a valid HWC layer");
10109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcInfo = mHwcLayers[hwcId];
10139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcLayer = hwcInfo.layer;
10149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
10159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(type).c_str(), static_cast<int>(callIntoHwc));
10169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcInfo.compositionType != type) {
10179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("    actually setting");
10189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        hwcInfo.compositionType = type;
10199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (callIntoHwc) {
10209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            auto error = hwcLayer->setCompositionType(type);
10219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
10229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    "composition type %s: %s (%d)", mName.string(),
10239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(type).c_str(), to_string(error).c_str(),
10249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(error));
10259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
10269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
10309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getCompositionType called without a valid HWC layer");
10329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return HWC2::Composition::Invalid;
10339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).compositionType;
10359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::setClearClientTarget(int32_t hwcId, bool clear) {
10389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setClearClientTarget called without a valid HWC layer");
10409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
10419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcLayers[hwcId].clearClientTarget = clear;
10439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::getClearClientTarget(int32_t hwcId) const {
10469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcLayers.count(hwcId) == 0) {
10479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getClearClientTarget called without a valid HWC layer");
10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mHwcLayers.at(hwcId).clearClientTarget;
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10541681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
10551681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
10561681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
10571681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
10581681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
10591681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
10601681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
10611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
10621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
10631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
10641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
1065cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozauint64_t Layer::getHeadFrameNumber() const {
1066cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mQueueItemLock);
1067cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (!mQueueItems.empty()) {
1068cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mQueueItems[0].mFrameNumber;
1069cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    } else {
1070cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return mCurrentFrameNumber;
10717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1072cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza}
10737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1074cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stozabool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1075cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    if (point->getFrameNumber() <= mCurrentFrameNumber) {
1076cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Don't bother with a SyncPoint, since we've already latched the
1077cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // relevant frame
1078cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        return false;
10797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
1080cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1081cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1082cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mLocalSyncPoints.push_back(point);
1083cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    return true;
10847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
10857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
108613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
108713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
108813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
108913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
109013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
109113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
109313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1094ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
1095ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
1096ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
1097ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
1098ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
1099ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1100ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11015773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
1102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
1104ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
11055773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
11065773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
11075773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
1108dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
11095773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
11105773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
1111dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
1112ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
1113ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1118c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1119c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
112013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
11211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
1122c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
1123c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
112613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
112713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
112813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
11296c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
1130f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
11313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1132ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1133ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
1134ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
1135ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
1136ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
11373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
11385cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
1141ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
11424125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
1143a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
1144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
1145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
1146db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
1147a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
1148db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
1149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
1150a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
1151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
11524125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
1153a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
1154a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
1155231160866738f6ed2175701f300fed1a8e8e02b0Dan Stozabool Layer::isSecure() const
1156231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza{
1157231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    const Layer::State& s(mDrawingState);
1158231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza    return (s.flags & layer_state_t::eLayerSecure);
1159231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza}
1160231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza
11617a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
11627a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
1163a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
11647a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
11657a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
11667a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
1167b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
116913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
117313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
119813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
119913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
12007dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::pushPendingState() {
12017dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mCurrentState.modified) {
12027dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return;
12037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If this transaction is waiting on the receipt of a frame, generate a sync
12067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // point and send it to the remote layer.
12077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (mCurrentState.handle != nullptr) {
12087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
12097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        sp<Layer> handleLayer = handle->owner.promote();
12107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (handleLayer == nullptr) {
12117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            ALOGE("[%s] Unable to promote Layer handle", mName.string());
12127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // If we can't promote the layer we are intended to wait on,
12137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // then it is expired or otherwise invalid. Allow this transaction
12147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // to be applied as per normal (no synchronization).
12157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            mCurrentState.handle = nullptr;
12163bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos        } else {
12173bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos            auto syncPoint = std::make_shared<SyncPoint>(
12183bddd5b7731fafd2c60e75416ccd091972d196aePablo Ceballos                    mCurrentState.frameNumber);
1219cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (handleLayer->addSyncPoint(syncPoint)) {
1220cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.push_back(std::move(syncPoint));
1221cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            } else {
1222cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // We already missed the frame we're supposed to synchronize
1223cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // on, so go ahead and apply the state update
1224cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mCurrentState.handle = nullptr;
1225cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
12267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
12277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        // Wake us up to check if the frame has been received
12297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
12307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.push_back(mCurrentState);
12327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::popPendingState() {
12357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    auto oldFlags = mCurrentState.flags;
12367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState = mPendingStates[0];
1237cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
12387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            (mCurrentState.flags & mCurrentState.mask);
12397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mPendingStates.removeAt(0);
12417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozabool Layer::applyPendingStates() {
12447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    bool stateUpdateAvailable = false;
12457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    while (!mPendingStates.empty()) {
12467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (mPendingStates[0].handle != nullptr) {
12477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.empty()) {
12487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // If we don't have a sync point for this, apply it anyway. It
12497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // will be visually wrong, but it should keep us from getting
12507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // into too much trouble.
12517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                ALOGE("[%s] No local sync point found", mName.string());
12527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
12537dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
12547dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                continue;
12557dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
12567dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1257cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            if (mRemoteSyncPoints.front()->getFrameNumber() !=
1258cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    mPendingStates[0].frameNumber) {
1259cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                ALOGE("[%s] Unexpected sync point frame number found",
1260cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        mName.string());
1261cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1262cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                // Signal our end of the sync point and then dispose of it
1263cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
1264cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mRemoteSyncPoints.pop_front();
1265cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                continue;
1266cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1267cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
12687dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            if (mRemoteSyncPoints.front()->frameIsAvailable()) {
12697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Apply the state update
12707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                popPendingState();
12717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                stateUpdateAvailable = true;
12727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                // Signal our end of the sync point and then dispose of it
12747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.front()->setTransactionApplied();
12757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                mRemoteSyncPoints.pop_front();
1276792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza            } else {
1277792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza                break;
12787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
12797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        } else {
12807dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            popPendingState();
12817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            stateUpdateAvailable = true;
12827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
12837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12847dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12857dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // If we still have pending updates, wake SurfaceFlinger back up and point
12867dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // it at this layer so we can process them
12877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!mPendingStates.empty()) {
12887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        setTransactionFlags(eTransactionNeeded);
12897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        mFlinger->setTransactionFlags(eTraversalNeeded);
12907dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
12917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12927dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
12937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    return stateUpdateAvailable;
12947dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
12957dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
12967dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::notifyAvailableFrames() {
1297cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    auto headFrameNumber = getHeadFrameNumber();
1298cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    Mutex::Autolock lock(mLocalSyncPointMutex);
1299cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza    for (auto& point : mLocalSyncPoints) {
1300cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (headFrameNumber >= point->getFrameNumber()) {
1301cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            point->setFrameAvailable();
1302cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
13037dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13047dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
13057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
130613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
13071c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
13081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13097dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
13107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    if (!applyPendingStates()) {
13117dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        return 0;
13127dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
13137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
13141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
13151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
13181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
1319a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1320a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
1321cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
13229d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
13236905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1324419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1325419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1326419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1327419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
13281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
13291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
13301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
13311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
13321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
13331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
13341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
13351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
13361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
13371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
13381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
13391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
13401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
13411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
13421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
13431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
13441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
13451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
13461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
13471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
13481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
13491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
13501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
13511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
13521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
13531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
13541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
13551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
13561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
1357a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
13582a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
13592a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
1360bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
13611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1363cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
13640cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
13650cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
13661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
13671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
13680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
13699e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
137013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
13710cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
13720cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
13730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
13740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
13750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
13760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
13770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
13789e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
13799e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
13809e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
13819e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
13820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
13830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
13840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
13850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
13860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
138713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
138813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
138913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
139013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
13911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
13921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
139313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
139413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
139613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
139713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
139813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
139913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
140113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
140213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
140313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
140413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
140513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
14061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
14071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
140813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
140913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
141013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
141113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
141213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
141313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
141713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
1418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
1419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
142113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
142213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
142313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
142413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
142513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
142613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
142713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
142813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
142913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
143013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
143113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
143213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
14337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
143413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
143513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
143613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
143713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
143813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
143913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
144113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
14427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
144313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
144413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
144513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
144613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
144713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
144813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
144913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
145013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
14517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
145213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
145313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
145413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
14559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
14569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool Layer::setAlpha(float alpha) {
14579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
145813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
14599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
146013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
146113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
146213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
146313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
14647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
146513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
146613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
146713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
147013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
147113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
147313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
147513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
147613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
14772ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
14787dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
147913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
148013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
148213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
148313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
148413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
148513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
148613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
148713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
14887dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.mask = mask;
14897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
149013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
149113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
149213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
149313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
149413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
149513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
149613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
149713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
14987dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
149913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
150013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
150113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
150213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
150313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
150413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
150513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
150613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
150713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
15087dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
150913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
151013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1511a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1512a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
15137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozavoid Layer::deferTransactionUntil(const sp<IBinder>& handle,
15147dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        uint64_t frameNumber) {
15157dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.handle = handle;
15167dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.frameNumber = frameNumber;
15177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // We don't set eTransactionNeeded, because just receiving a deferral
15187dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // request without any other state updates shouldn't actually induce a delay
15197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = true;
15207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    pushPendingState();
1521792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.handle = nullptr;
1522792e529dee5b6cf839b982b4b06a37fbf1d3e28aDan Stoza    mCurrentState.frameNumber = 0;
15237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    mCurrentState.modified = false;
15247dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza}
15257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1526ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1527ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1528ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1529ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1530ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1531ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1532ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1533ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1534ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1535ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1536ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1537ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15426b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
1543ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mSidebandStreamChanged || mAutoRefresh) {
1544d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza        return true;
1545d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza    }
1546d87defaf486ff4e9c0066754564851cfb7be49edDan Stoza
15476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
15480eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    if (mQueueItems.empty()) {
15490eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza        return false;
15500eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    }
15510eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    auto timestamp = mQueueItems[0].mTimestamp;
15526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
15536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
15540eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
15550eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    // Ignore timestamps more than a second in the future
15560eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
15570eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
15580eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
15590eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza            expectedPresent);
15600eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza
15610eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    bool isDue = timestamp < expectedPresent;
15620eb2d398669bf11207c0fb22b11439250da0c8dcDan Stoza    return isDue || !isPlausible;
15636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
15646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
15654d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
15664d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1567ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
156899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
156999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1570d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1571d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1572bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
157382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
157482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1575bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1576789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
157782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
157882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
157982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
158082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
158182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
158282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
158382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1584d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
15859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
15869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
15879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
158882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
15899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1590789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
159182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
159282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
159382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
159482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
159582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
159682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
159782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
159882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
159982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1600d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1601d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1602d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1603d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
16049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid Layer::releasePendingBuffer() {
16069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mSurfaceFlingerConsumer->releasePendingBuffer();
16079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
16089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
16099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1610da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
161113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
16129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
16139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
16149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            && (mActiveBuffer != NULL || mSidebandStream != NULL);
16159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
161613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1617afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
16189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
1619da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1620da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
16214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
16241c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1625399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1626399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1627399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
162812e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        if (mSidebandStream != NULL) {
162912e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            setTransactionFlags(eTransactionNeeded);
163012e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza            mFlinger->setTransactionFlags(eTraversalNeeded);
163112e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza        }
16325bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
16335bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
16345bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
16355bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1636399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1637399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
16384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
1639ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    if (mQueuedFrames > 0 || mAutoRefresh) {
164099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
164199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
164299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
164399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
164499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
164599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
16464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
16474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
164899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
164999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1650351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
16514125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
16524125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1653351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1654db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1655bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
16562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
16572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
16582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
16591681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
16602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
16611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
16622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
16631681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
16641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
16652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
16662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
166811611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
16692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
16702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
16712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
16722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
16742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
16752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
16772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
16782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
16792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
16802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
16812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
16832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
16842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
16862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
16872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
16882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
16892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
16902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
16912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
16922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
16932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
16942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
16952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
16962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
16972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
16982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
16992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
17002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
17012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
17032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
17042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
17052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
17076905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
17082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
17092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
17106905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
17112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
17122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
17132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
17142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
17152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
17162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
17172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
17182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
17192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
17202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
17212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
17222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
17232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
17242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
17252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17271681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
17282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
17292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
17304824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
17311681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
17321681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
17332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
17342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
17352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
17362ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
17372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
17382ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
17392ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
17402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
17412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
17422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
17432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
17446c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
17456c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
17466c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
17476c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
17486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
17496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
17506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
17516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
17526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
17536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
17542ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
17552ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
17562ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
17572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
17582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
17592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
17602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
17621681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
17632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
17647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1765cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Check all of our local sync points to ensure that all transactions
1766cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // which need to have been applied prior to the frame which is about to
1767cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // be latched have signaled
1768cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1769cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        auto headFrameNumber = getHeadFrameNumber();
1770cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool matchingFramesFound = false;
1771cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        bool allTransactionsApplied = true;
17727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        {
1773cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1774cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            for (auto& point : mLocalSyncPoints) {
1775cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (point->getFrameNumber() > headFrameNumber) {
17767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                    break;
17777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                }
1778cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
17797dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza                matchingFramesFound = true;
1780cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1781cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!point->frameIsAvailable()) {
1782cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // We haven't notified the remote layer that the frame for
1783cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // this point is available yet. Notify it now, and then
1784cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // abort this attempt to latch.
1785cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point->setFrameAvailable();
1786cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    allTransactionsApplied = false;
1787cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    break;
1788cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1789cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1790cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                allTransactionsApplied &= point->transactionIsApplied();
17917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            }
1792a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza        }
1793a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza
1794cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        if (matchingFramesFound && !allTransactionsApplied) {
1795cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            mFlinger->signalLayerUpdate();
1796cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            return outDirtyRegion;
1797cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1798cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1799063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // This boolean is used to make sure that SurfaceFlinger's shadow copy
1800063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // of the buffer queue isn't modified when the buffer queue is returning
1801063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // BufferItem's that weren't actually queued. This can happen in single
1802063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        // buffer mode.
1803063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        bool queuedBuffer = false;
180441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1805ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
1806cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                mLastFrameNumberReceived);
18071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
18081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
18091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
18101585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
18111585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
1812ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1813ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // If the buffer has been rejected, remove it from the shadow queue
1814ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // and return early
1815063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
1816063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                Mutex::Autolock lock(mQueueItemLock);
1817063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                mQueueItems.removeAt(0);
1818063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos                android_atomic_dec(&mQueuedFrames);
1819063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            }
1820ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            return outDirtyRegion;
182165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
182265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // This can occur if something goes wrong when trying to create the
182365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // EGLImage for this buffer. If this happens, the buffer has already
182465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // been released, so we need to clean up the queue and bug out
182565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // early.
1826063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            if (queuedBuffer) {
182765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                Mutex::Autolock lock(mQueueItemLock);
182865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                mQueueItems.clear();
182965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza                android_atomic_and(0, &mQueuedFrames);
183065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            }
183165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
183265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // Once we have hit this state, the shadow queue may no longer
183365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // correctly reflect the incoming BufferQueue's contents, so even if
183465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // updateTexImage starts working, the only safe course of action is
183565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            // to continue to ignore updates.
183665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            mUpdateTexImageFailed = true;
183765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza
183865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza            return outDirtyRegion;
18391585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
18401585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
1841063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if (queuedBuffer) {
1842063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos            // Autolock scope
1843ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1844ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
18456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
1846ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
1847ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // Remove any stale buffers that have been dropped during
1848ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            // updateTexImage
1849ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1850ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                mQueueItems.removeAt(0);
1851ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza                android_atomic_dec(&mQueuedFrames);
1852ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza            }
1853ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
18546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
18556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
18566b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1857ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza
18581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
18591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
1860063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1861ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                || mAutoRefresh) {
18621585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
18631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
18641585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
18651585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1866a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1867a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
18684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1869a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1870d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1871351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1872bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1873e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1874e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
18754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1876e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1877da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
18784824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1879702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1880e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
18812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
18822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1883ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
18842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1885702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1886bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1887bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1888bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1889702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1890702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1891702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1892702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1893702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1894702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1895702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1896ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1897702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1898702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1899702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1900e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1901e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1902702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1903702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1904ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1905702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1906702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1907702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1908702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
19094125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1910702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1911702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1912702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1913cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1914cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1915cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // Remove any sync points corresponding to the buffer which was just
1916cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        // latched
1917cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        {
1918cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            Mutex::Autolock lock(mLocalSyncPointMutex);
1919cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            auto point = mLocalSyncPoints.begin();
1920cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            while (point != mLocalSyncPoints.end()) {
1921cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if (!(*point)->frameIsAvailable() ||
1922cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                        !(*point)->transactionIsApplied()) {
1923cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // This sync point must have been added since we started
1924cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    // latching. Don't drop it yet.
1925cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
1926cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    continue;
1927cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1928cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
1929cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1930cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    point = mLocalSyncPoints.erase(point);
1931cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                } else {
1932cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                    ++point;
1933cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza                }
1934cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza            }
1935cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza        }
1936cac353808ec1048333d7fd2f3d596fb4db567aa3Dan Stoza
19374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
19381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
19391c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
19411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
194713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
194813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
194913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
195013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
195113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
195213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
195303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
195403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
195503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
195613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
195713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
195813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
195913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
196013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
196113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
196213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
196313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
196413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
196513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
196613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
196713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
196813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
196913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
197013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
197113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
197213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
197313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
197413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
197513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
197613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
197713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
197813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
19801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
19811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
198213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
198474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
198513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
198613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
19873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
198813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
199013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1991ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
199213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
199313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
199474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
199513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
199613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
19979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#ifdef USE_HWC2
19989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
19999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#else
200013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
20019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#endif
200213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
200313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
200413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
200513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
20064125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
200713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
200813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
200913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
201013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
20111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2012a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
2013a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
20141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
20151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
20161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
20171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
2018a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
20191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
202074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
20211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
2022ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
20236905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
2024a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
20256905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
20261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2027bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
202874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
2029bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
2030d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
2031d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
2032d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
2033d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
203482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
203582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
2036d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
2037d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
203825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
203925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
20406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
20416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
20426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
20436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2044d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
2045d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
2046d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
2047d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
204813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
204913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
205013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
205113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
205213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
2053b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
2054b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
205513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
205613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
205713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
2058a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
2059a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
2060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
20613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
20643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
20653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
20683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
20693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
2070