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