Layer.cpp revision a1f47b90ab53af978be45b8bda16c5d084ae66e6
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 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 283330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 309cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 319cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 341f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 38a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopiantemplate <typename T> inline T min(T a, T b) { 47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return a<b ? a : b; 48ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian} 49ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5296f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, 5396f0819f81293076e652792794a961543e6750d7Mathias Agopian DisplayID display, const sp<Client>& client) 5496f0819f81293076e652792794a961543e6750d7Mathias Agopian : LayerBaseClient(flinger, display, client), 551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsBlending(true), 57d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mNeedsDithering(false), 58b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 5916f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp(false), 6016f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByDRM(false), 611f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mTextureManager(), 62a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager(mTextureManager), 63733189d408e13b54fd70971b265244367efd0f51Mathias Agopian mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false) 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 69bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // FIXME: must be called from the main UI thread 70bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 71bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 73b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // we can use getUserClientUnsafe here because we know we're 74b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // single-threaded at that point. 75b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 76b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ourClient != 0) { 77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ourClient->detachLayer(this); 78b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 81b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient, 82b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedClient* sharedClient, int32_t token) 8396f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 84579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<SharedBufferServer> lcblk = new SharedBufferServer( 85b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sharedClient, token, mBufferManager.getDefaultBufferCount(), 86b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian getIdentity()); 8796f0819f81293076e652792794a961543e6750d7Mathias Agopian 88579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 89dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian sp<UserClient> ourClient(mUserClientRef.getClient()); 90dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 91dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian /* 92dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * Here it is guaranteed that userClient != ourClient 93dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * (see UserClient::getTokenForSurface()). 94dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 95dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * We release the token used by this surface in ourClient below. 96dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * This should be safe to do so now, since this layer won't be attached 97dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * to this client, it should be okay to reuse that id. 98dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 99dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * If this causes problems, an other solution would be to keep a list 100dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * of all the {UserClient, token} ever used and release them when the 101dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * Layer is destroyed. 102dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 103dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian */ 104dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 105dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian if (ourClient != 0) { 106dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian ourClient->detachLayer(this); 107dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian } 108dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 109dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian status_t err = mUserClientRef.setToken(userClient, lcblk, token); 110579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE_IF(err != NO_ERROR, 111579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian "ClientRef::setToken(%p, %p, %u) failed", 112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian userClient.get(), lcblk.get(), token); 113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 114579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (err == NO_ERROR) { 115579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // we need to free the buffers associated with this surface 116b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 11796f0819f81293076e652792794a961543e6750d7Mathias Agopian 118b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return err; 119b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 12096f0819f81293076e652792794a961543e6750d7Mathias Agopian 121b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::getToken() const 122b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mUserClientRef.getToken(); 12496f0819f81293076e652792794a961543e6750d7Mathias Agopian} 12596f0819f81293076e652792794a961543e6750d7Mathias Agopian 126579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::getClient() const 127579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 128579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return mUserClientRef.getClient(); 129579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 130579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 131d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 132d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 133d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 134d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 135b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 13896f0819f81293076e652792794a961543e6750d7Mathias Agopian // wake up the condition 13996f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->setStatus(NO_INIT); 14096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 14148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 145a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this))); 146a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch() 1509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 151bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: Called from the main UI thread 152bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 154f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 155bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 156bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 157bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mWidth = mHeight = 0; 1589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 1599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 161f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 164401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 170401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 171ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 172ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 173ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 180401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 181401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 182a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 183a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 184cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 185ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mWidth = w; 186cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 187eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 188eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqFormat = format; 189eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqWidth = w; 190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqHeight = h; 191eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 1923330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 19316f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 19416f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false; 1953b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 && 1963b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy (flags & ISurfaceComposer::eOpaque) == 0; 197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 198401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // we use the red index 199401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 200401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 201401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 202401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 206a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setGeometry(hwc_layer_t* hwcl) 207a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 208a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->compositionType = HWC_FRAMEBUFFER; 209a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->hints = 0; 210a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->flags = 0; 211a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->transform = 0; 212a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->blending = HWC_BLENDING_NONE; 213a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 214a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can't do alpha-fade with the hwc HAL 215a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const State& s(drawingState()); 216a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (s.alpha < 0xFF) { 217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->flags = HWC_SKIP_LAYER; 218a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian return; 219a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 220a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 221a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can only handle simple transformation 222a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (mOrientation & Transform::ROT_INVALID) { 223a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->flags = HWC_SKIP_LAYER; 224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian return; 225a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 226a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 22786bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian Transform tr(Transform(mOrientation) * Transform(mBufferTransform)); 22886bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian hwcl->transform = tr.getOrientation(); 229a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 230a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (needsBlending()) { 231a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->blending = mPremultipliedAlpha ? 232a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; 233a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 234a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 235a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->displayFrame.left = mTransformedBounds.left; 236a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->displayFrame.top = mTransformedBounds.top; 237a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->displayFrame.right = mTransformedBounds.right; 238a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->displayFrame.bottom = mTransformedBounds.bottom; 239a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 240a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->visibleRegionScreen.rects = 241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian reinterpret_cast<hwc_rect_t const *>( 242a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian visibleRegionScreen.getArray( 243a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian &hwcl->visibleRegionScreen.numRects)); 244a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 245a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 246a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setPerFrameData(hwc_layer_t* hwcl) { 247a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (buffer == NULL) { 249da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // this can happen if the client never drew into this layer yet, 250da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // or if we ran out of memory. In that case, don't let 251da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // HWC handle it. 252da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian hwcl->flags |= HWC_SKIP_LAYER; 253a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwcl->handle = NULL; 254a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian return; 255a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 256040481419473cb9913b632cd8973b1d7065f9c9cLouis Huemiller hwcl->handle = buffer->handle; 257f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian 258f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian if (!mBufferCrop.isEmpty()) { 259f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.left = mBufferCrop.left; 260f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.top = mBufferCrop.top; 261f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.right = mBufferCrop.right; 262f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.bottom = mBufferCrop.bottom; 263f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian } else { 264f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.left = 0; 265f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.top = 0; 266f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.right = buffer->width; 267f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian hwcl->sourceCrop.bottom = buffer->height; 268f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian } 269a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 270a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 273d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 2748f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian if (buffer == NULL) { 2758f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // this situation can happen if we ran out of memory for instance. 2768f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // not much we can do. continue to use whatever texture was bound 2778f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // to this context. 2788f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian return; 2798f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian } 2808f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 2811f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (mGLExtensions.haveDirectTexture()) { 282d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 283d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 284d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // not sure what we can do here... 285d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian goto slowpath; 286076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } else { 288fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath: 289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GGLSurface t; 290f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) { 291f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 292f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 293f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian res, strerror(res), buffer.get()); 294f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian if (res == NO_ERROR) { 295f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian mBufferManager.loadTexture(dirty, t); 296f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian buffer->unlock(); 297f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian } 298f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian } else { 299f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian // we can't do anything 300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianvoid Layer::drawForSreenShot() const 30574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 306733189d408e13b54fd70971b265244367efd0f51Mathias Agopian const bool currentFiltering = mNeedsFiltering; 307733189d408e13b54fd70971b265244367efd0f51Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = true; 30874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian LayerBase::drawForSreenShot(); 309733189d408e13b54fd70971b265244367efd0f51Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering; 31074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 31174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 314d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Texture tex(mBufferManager.getActiveTexture()); 315d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (tex.name == -1LU) { 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 319179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian under.orSelf(layer->visibleRegionScreen); 333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 3370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian clearWithOpenGL(holes, 0, 0, 0, 1); 338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 341d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian drawWithOpenGL(clip, tex); 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 344a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const 345a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 346a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 347733189d408e13b54fd70971b265244367efd0f51Mathias Agopian // if our buffer is not the same size than ourselves, 348733189d408e13b54fd70971b265244367efd0f51Mathias Agopian // we need filtering. 349733189d408e13b54fd70971b265244367efd0f51Mathias Agopian Mutex::Autolock _l(mLock); 350733189d408e13b54fd70971b265244367efd0f51Mathias Agopian if (mNeedsScaling) 351a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return true; 352a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 353a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return LayerBase::needsFiltering(); 354a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 355a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 356b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 357b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 358b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 359b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 360b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 361b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 362b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // oops, the client is already gone 363b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return DEAD_OBJECT; 364b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 365b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 366bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 367bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t err = lcblk->resize(bufferCount); 36854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis if (err == NO_ERROR) { 36954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 37054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferManager.resize(bufferCount, mFlinger, dpy); 37154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 372b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 373b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 374b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 375b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 376a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 377a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t usage) 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 38148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 382b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 383a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 38848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 38948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 392b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 39348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 39448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 39548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 39648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 397076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 398cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 399cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 400cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 401076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 40248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 403208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian status_t err = NO_ERROR; 404a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, h, f; 40548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 40648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 407eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 408eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian // zero means default 409e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian const bool fixedSize = reqWidth && reqHeight; 410eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqFormat) reqFormat = mFormat; 411eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqWidth) reqWidth = mWidth; 412eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqHeight) reqHeight = mHeight; 413eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 414eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian w = reqWidth; 415eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian h = reqHeight; 416eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian f = reqFormat; 417eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 418eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) || 419eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian (reqFormat != mReqFormat)) { 420eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqWidth = reqWidth; 421eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqHeight = reqHeight; 422eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqFormat = reqFormat; 423e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian mFixedSize = fixedSize; 424733189d408e13b54fd70971b265244367efd0f51Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 425eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 426a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian lcblk->reallocateAllExcept(index); 427a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 42848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 42948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 430208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // here we have to reallocate a new buffer because the buffer could be 431208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // used as the front buffer, or by a client in our process 432208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // (eg: status bar), and we can't release the handle under its feet. 4333330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 434208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 435208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian err = buffer->initCheck(); 436cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 437cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 438678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 439cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 440cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 441cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 443cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 4447e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 4457e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 448cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 44948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 450a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager.attachBuffer(index, buffer); 451f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 453f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 454f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 4553330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 4563330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 4573330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 4583330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 4593330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 4603330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 4613330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 4623330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 4633330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 4643330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 4653330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 4663330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 4673330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 4683330b203039dea366d4981db1408a460134b2d2cMathias Agopian 4693330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 4703330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 4713330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 4723330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 4733330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 4743330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 4753330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 47689141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian // request EGLImage for all buffers 47789141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 4783330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 47916f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten if (mProtectedByApp || mProtectedByDRM) { 48016f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten // need a hardware-protected path to external video sink 48116f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten usage |= GraphicBuffer::USAGE_PROTECTED; 48216f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten } 4833330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 4843330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 4853330b203039dea366d4981db1408a460134b2d2cMathias Agopian 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 491a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 492a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian (front.requested_h != temp.requested_h); 493a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 494a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 495cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 497a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 498a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian this, 499a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(temp.requested_w), int(temp.requested_h), 500a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(front.requested_w), int(front.requested_h)); 501a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 502a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!isFixedSize()) { 503a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // we're being resized and there is a freeze display request, 504a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // acquire a freeze lock, so that the screen stays put 505a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // until we've redrawn at the new size; this is to avoid 506a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // glitches upon orientation changes. 507a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (mFlinger->hasFreezeRequest()) { 508a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // if the surface is hidden, don't try to acquire the 509a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // freeze lock, since hidden surfaces may never redraw 510a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 511a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 512a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 514caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 515a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 516a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // the drawing state's size 517a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Layer::State& editDraw(mDrawingState); 518a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_w = temp.requested_w; 519a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_h = temp.requested_h; 520df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 521a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size, form this point on, when the client request 522a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // a buffer, it'll get the new size. 523a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 5246656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 525b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 527b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 52896f0819f81293076e652792794a961543e6750d7Mathias Agopian // all buffers need reallocation 52996f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->reallocateAll(); 53096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 531a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } else { 532a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size 533a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 534a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 536cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 549cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 550cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 551cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 552733189d408e13b54fd70971b265244367efd0f51Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 555a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const { 556a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mLock); 557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mFixedSize; 558a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 559a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 566b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 567b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 568b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 56996f0819f81293076e652792794a961543e6750d7Mathias Agopian // client died 57096f0819f81293076e652792794a961543e6750d7Mathias Agopian recomputeVisibleRegions = true; 57196f0819f81293076e652792794a961543e6750d7Mathias Agopian return; 57296f0819f81293076e652792794a961543e6750d7Mathias Agopian } 57396f0819f81293076e652792794a961543e6750d7Mathias Agopian 574cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 575d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf == NOT_ENOUGH_DATA) { 576d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // NOTE: This is not an error, it simply means there is nothing to 577d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // retire. The buffer is locked because we will use it 578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 581d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 582d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf < NO_ERROR) { 583b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 584d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 585d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 586d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 587d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 588cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 589da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 590da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); 591d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 592b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 593d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mPostedDirtyRegion.clear(); 594d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return; 595d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 597da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian if (noActiveBuffer) { 598da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // we didn't have an active buffer, we need to recompute 599da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // our visible region 600da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian recomputeVisibleRegions = true; 601da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian } 602da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6033330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 604d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 605b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the dirty region 606d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 607d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 608d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 609d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 610d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 611d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 612d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 613d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 614df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 615d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 616d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 617d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 618d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 619d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 620d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 621d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 622d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 623d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 624d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 625d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 626d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 627d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 628d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 629d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 630d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 631d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 632d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 633d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 634d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 635d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 636d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 6378f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 638d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 639d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 640d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 641b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 642b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the crop region 643b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian setBufferCrop( lcblk->getCrop(buf) ); 644b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 645b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the transformation 646b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian setBufferTransform( lcblk->getTransform(buf) ); 647b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 648d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 649d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 650d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 651d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 652d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 653d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 654caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 655caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 656e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 657e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 658e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 659e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 661245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 662245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 663245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 664245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 665245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * for instance, a degenerate case could be that the user did an empty 666245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * update but repainted the buffer with appropriate content (after a 667245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * resize for instance). 668245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian */ 669245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian reloadTexture( mPostedDirtyRegion ); 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 691c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 692c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 6931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian // (because it may never be updated and therefore never release it) 694c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 695c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 6991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 7001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 703b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 704b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian uint32_t totalTime = 0; 705b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 706b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 707b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian totalTime= stats.totalTime; 708b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result.append( lcblk->dump(" ") ); 709b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 710b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 7111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 7121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 7131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w0=0, h0=0, s0=0; 7141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w1=0, h1=0, s1=0; 7151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf1 != 0) { 7211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w1 = buf1->getWidth(); 7221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h1 = buf1->getHeight(); 7231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s1 = buf1->getStride(); 7241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 7271b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 7281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 729b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mFormat, w0, h0, s0, w1, h1, s1, 730b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian getFreezeLock().get(), totalTime); 7311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 7331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 7341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::ClientRef() 738579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian : mControlBlock(0), mToken(-1) { 739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 740b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::~ClientRef() { 742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 743b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 744b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::ClientRef::getToken() const { 745b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mLock); 746b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mToken; 747b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 748b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 749579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const { 750579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian Mutex::Autolock _l(mLock); 751579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return mUserClient.promote(); 752579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 753579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 754b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 755579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const sp<SharedBufferServer>& sharedClient, int32_t token) { 756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mLock); 757579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 758579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian { // scope for strong mUserClient reference 759579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<UserClient> userClient(mUserClient.promote()); 760579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (mUserClient != 0 && mControlBlock != 0) { 761579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock->setStatus(NO_INIT); 762579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 763579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 764579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 765b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mUserClient = uc; 766b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mToken = token; 767579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock = sharedClient; 768b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 769b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 770b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 771b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 772b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mUserClient.promote(); 773b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 774b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 775b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// this class gives us access to SharedBufferServer safely 776b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// it makes sure the UserClient (and its associated shared memory) 777b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// won't go away while we're accessing it. 778b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref) 779579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian : mControlBlock(0) 780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 781b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(ref.mLock); 782b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mUserClientStrongRef = ref.mUserClient.promote(); 783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mUserClientStrongRef != 0) 784579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock = ref.mControlBlock; 785579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 786579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 787579b3f88d03d06b897b778bd11818f5104677d1dMathias AgopianLayer::ClientRef::Access::~Access() 788579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 789b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 790b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 792b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 793d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 794bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 795420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex(-1), mFailover(false) 796bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 797bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 798bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 799bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager() 800d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 801d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 802d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 80354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennisstatus_t Layer::BufferManager::resize(size_t size, 80454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis const sp<SurfaceFlinger>& flinger, EGLDisplay dpy) 805bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 806bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 80754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 80854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis if (size < mNumBuffers) { 80954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Move the active texture into slot 0 810420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian BufferData activeBufferData = mBufferData[mActiveBufferIndex]; 811420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mBufferData[mActiveBufferIndex] = mBufferData[0]; 81254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[0] = activeBufferData; 813420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex = 0; 81454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 81554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Free the buffers that are no longer needed. 81654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis for (size_t i = size; i < mNumBuffers; i++) { 81754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].buffer = 0; 81854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 81954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Create a message to destroy the textures on SurfaceFlinger's GL 82054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // thread. 82154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis class MessageDestroyTexture : public MessageBase { 82254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis Image mTexture; 82354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis EGLDisplay mDpy; 82454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis public: 82554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis MessageDestroyTexture(const Image& texture, EGLDisplay dpy) 82654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis : mTexture(texture), mDpy(dpy) { } 82754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis virtual bool handler() { 82854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis status_t err = Layer::BufferManager::destroyTexture( 82954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis &mTexture, mDpy); 83054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis LOGE_IF(err<0, "error destroying texture: %d (%s)", 83154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mTexture.name, strerror(-err)); 83254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis return true; // XXX: err == 0; ???? 83354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 83454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis }; 83554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 83654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis MessageDestroyTexture *msg = new MessageDestroyTexture( 83754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture, dpy); 83854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 83954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Don't allow this texture to be cleaned up by 84054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // BufferManager::destroy. 84154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture.name = -1U; 84254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture.image = EGL_NO_IMAGE_KHR; 84354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 84454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Post the message to the SurfaceFlinger object. 84554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis flinger->postMessageAsync(msg); 84654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 84754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 84854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 849bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mNumBuffers = size; 850bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 851d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 852d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 853d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging 854d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 855d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mBufferData[index].buffer; 856d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 857d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 858d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 859420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian BufferData const * const buffers = mBufferData; 860420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian Mutex::Autolock _l(mLock); 861420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBuffer = buffers[index].buffer; 862420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex = index; 863d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 864d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 865d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 866d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 867420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBufferIndex; 868d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 869d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 870d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 871bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Texture res; 872420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian if (mFailover || mActiveBufferIndex<0) { 873bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian res = mFailoverTexture; 874bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else { 875420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture; 876bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 877bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 878d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 879d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 880d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 881420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBuffer; 882d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 883d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 884da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopianbool Layer::BufferManager::hasActiveBuffer() const { 885420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBufferIndex >= 0; 886da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian} 887da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 888d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 889d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 890bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 891d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer; 892d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 893bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffer = buffers[index].buffer; 894bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = 0; 895d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return buffer; 896d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 897d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 898d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 899d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 900d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 901bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 902d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 903bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = buffer; 904bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].texture.dirty = true; 905d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 906d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 907d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 908d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 909d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 910bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 911bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian size_t num; 912bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian { // scope for the lock 913bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 914bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian num = mNumBuffers; 915bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 916bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[i].buffer = 0; 917bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 918bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 919bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 920bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 921d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 922d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 923d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 924d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 925d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 926d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 927d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 928d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 929b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t err = NO_INIT; 930420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian ssize_t index = mActiveBufferIndex; 931b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (index >= 0) { 9321f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (!mFailover) { 9331f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian Image& texture(mBufferData[index].texture); 9341f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian err = mTextureManager.initEglImage(&texture, dpy, buffer); 9351f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 9361f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // free all resources associated with using EGLImages. 9371f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (err == NO_ERROR) { 9381f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mFailover = false; 9391f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 9401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } else { 9411f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mFailover = true; 9421f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian const size_t num = mNumBuffers; 9431f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian for (size_t i=0 ; i<num ; i++) { 9441f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 9451f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 946e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber } 9471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } else { 9481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // we failed once, don't try again 9491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian err = BAD_VALUE; 950d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 951d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 952d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return err; 953d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 954d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 955d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture( 956d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const Region& dirty, const GGLSurface& t) 957d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 958d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 959d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 960d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 961bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 962bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 963bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->name != -1U) { 964bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian glDeleteTextures(1, &tex->name); 965bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->name = -1U; 966bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 967bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 968bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 969bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 970bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 971bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 972bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 973bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 974d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// --------------------------------------------------------------------------- 975d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 9769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 97796f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Layer>& owner) 97896f0819f81293076e652792794a961543e6750d7Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 9799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 9809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 9819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 9829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 983076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 984076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 985076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 986a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 987a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 988076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 9893330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 990076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 991076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 992bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 993bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * requestBuffer() cannot be called from the main thread 994bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 995bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 996bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 997a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 998076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 999076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 1000076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1002b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 1003b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 1004b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian status_t err = DEAD_OBJECT; 1005b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Layer> owner(getOwner()); 1006b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (owner != 0) { 1007bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 1008bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * setBufferCount() cannot be called from the main thread 1009bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 1010bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 1011bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 1012b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian err = owner->setBufferCount(bufferCount); 1013b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 1014b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 1015b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 1016b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 1021