Layer.cpp revision 5bf3abefb2745bf0c45b0814cfd44b4682060a6c
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), 555bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mFormat(PIXEL_FORMAT_NONE), 561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 57401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsBlending(true), 58d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mNeedsDithering(false), 59b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 6016f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp(false), 611f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mTextureManager(), 62a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager(mTextureManager), 635bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mWidth(0), mHeight(0), 647ffe3807506da6f052535ca0c790636e41a8e310Eric Hassold mNeedsScaling(false), mFixedSize(false) 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 70bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // FIXME: must be called from the main UI thread 71bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 73bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 74b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // we can use getUserClientUnsafe here because we know we're 75b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // single-threaded at that point. 76b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ourClient != 0) { 78b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ourClient->detachLayer(this); 79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 81d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 82b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient, 83b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedClient* sharedClient, int32_t token) 8496f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 85579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<SharedBufferServer> lcblk = new SharedBufferServer( 86b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sharedClient, token, mBufferManager.getDefaultBufferCount(), 87b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian getIdentity()); 8896f0819f81293076e652792794a961543e6750d7Mathias Agopian 89579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 90dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian sp<UserClient> ourClient(mUserClientRef.getClient()); 91dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 92dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian /* 93dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * Here it is guaranteed that userClient != ourClient 94dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * (see UserClient::getTokenForSurface()). 95dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 96dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * We release the token used by this surface in ourClient below. 97dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * This should be safe to do so now, since this layer won't be attached 98dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * to this client, it should be okay to reuse that id. 99dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 100dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * If this causes problems, an other solution would be to keep a list 101dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * of all the {UserClient, token} ever used and release them when the 102dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * Layer is destroyed. 103dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian * 104dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian */ 105dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 106dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian if (ourClient != 0) { 107dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian ourClient->detachLayer(this); 108dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian } 109dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian 110dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian status_t err = mUserClientRef.setToken(userClient, lcblk, token); 111579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE_IF(err != NO_ERROR, 112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian "ClientRef::setToken(%p, %p, %u) failed", 113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian userClient.get(), lcblk.get(), token); 114579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 115579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (err == NO_ERROR) { 116579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // we need to free the buffers associated with this surface 117b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 11896f0819f81293076e652792794a961543e6750d7Mathias Agopian 119b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return err; 120b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 12196f0819f81293076e652792794a961543e6750d7Mathias Agopian 122b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::getToken() const 123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 124b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mUserClientRef.getToken(); 12596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 12696f0819f81293076e652792794a961543e6750d7Mathias Agopian 127579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::getClient() const 128579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 129579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return mUserClientRef.getClient(); 130579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 131579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 132d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 133d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 134d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 135d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 13996f0819f81293076e652792794a961543e6750d7Mathias Agopian // wake up the condition 14096f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->setStatus(NO_INIT); 14196f0819f81293076e652792794a961543e6750d7Mathias Agopian } 14248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 143cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 144076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 146a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this))); 147a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch() 1519a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 152bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: Called from the main UI thread 153bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 155f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 156bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 157bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 158bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mWidth = mHeight = 0; 1599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 1609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 162f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 165401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 170401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 171401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 172ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 173ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 181401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 182401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 183a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 184a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 185cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 186ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mWidth = w; 187cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 188eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 189eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqFormat = format; 190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqWidth = w; 191eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqHeight = h; 192eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 1933330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 19416f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? 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 344ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 345ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 346ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 347ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 348ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 349ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 350ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 351ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const 352ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 353ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // If buffers where set with eOpaque flag, all buffers are known to 354ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // be opaque without having to check their actual format 355ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold if (mNeedsBlending && buffer != NULL) { 356ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold PixelFormat format = buffer->getPixelFormat(); 357ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 358ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold if (HARDWARE_IS_DEVICE_FORMAT(format)) { 359ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold return false; 360ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 361ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 362ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold PixelFormatInfo info; 363ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold status_t err = getPixelFormatInfo(format, &info); 364ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold if (!err && info.h_alpha <= info.l_alpha) { 365ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold return false; 366ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 367ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 368ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 369ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // Return opacity as determined from flags and format options 370ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // passed to setBuffers() 371ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold return mNeedsBlending; 372ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 373ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 374ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending() const 375ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 376ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold if (mBufferManager.hasActiveBuffer()) { 377ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold return needsBlending(mBufferManager.getActiveBuffer()); 378ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 379ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 380ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold return mNeedsBlending; 381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 382ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 383a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const 384a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 385a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 386733189d408e13b54fd70971b265244367efd0f51Mathias Agopian // if our buffer is not the same size than ourselves, 387733189d408e13b54fd70971b265244367efd0f51Mathias Agopian // we need filtering. 388733189d408e13b54fd70971b265244367efd0f51Mathias Agopian Mutex::Autolock _l(mLock); 389733189d408e13b54fd70971b265244367efd0f51Mathias Agopian if (mNeedsScaling) 390a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return true; 391a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 392a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return LayerBase::needsFiltering(); 393a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 394a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 3957a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 3967a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 3977a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer()); 3987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 3997a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4007a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 401b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 402b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 403b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 406b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 407b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // oops, the client is already gone 408b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return DEAD_OBJECT; 409b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 410b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t err = lcblk->resize(bufferCount); 41354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis if (err == NO_ERROR) { 41454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 41554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferManager.resize(bufferCount, mFlinger, dpy); 41654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 417b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 418b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 419b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 420b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 421a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 422a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t usage) 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4253330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 42648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 429a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 431a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 432a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 43348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 43448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 43848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 43948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 44048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 44148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 443cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 44748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 448208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian status_t err = NO_ERROR; 449a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, h, f; 45048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 45148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 452eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 453eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian // zero means default 454e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian const bool fixedSize = reqWidth && reqHeight; 455eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqFormat) reqFormat = mFormat; 456eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqWidth) reqWidth = mWidth; 457eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if (!reqHeight) reqHeight = mHeight; 458eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 459eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian w = reqWidth; 460eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian h = reqHeight; 461eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian f = reqFormat; 462eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 463eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) || 464eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian (reqFormat != mReqFormat)) { 465eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqWidth = reqWidth; 466eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqHeight = reqHeight; 467eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian mReqFormat = reqFormat; 468e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian mFixedSize = fixedSize; 469733189d408e13b54fd70971b265244367efd0f51Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 470eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 471a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian lcblk->reallocateAllExcept(index); 472a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 47348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 47448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 475208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // here we have to reallocate a new buffer because the buffer could be 476208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // used as the front buffer, or by a client in our process 477208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian // (eg: status bar), and we can't release the handle under its feet. 4783330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 479208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 480208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian err = buffer->initCheck(); 481cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 482cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 483678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 484cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 485cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 486cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 488cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 4897e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 4907e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 493cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 49448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 495a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager.attachBuffer(index, buffer); 496f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 497cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 498f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 499f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 5003330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 5013330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 5023330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 5033330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 5043330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 5053330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 5063330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 5073330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 5083330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 5093330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 5103330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 5113330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 5123330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 5133330b203039dea366d4981db1408a460134b2d2cMathias Agopian 5143330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 5153330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 5163330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 5173330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 5183330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 5193330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 5203330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 52189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian // request EGLImage for all buffers 52289141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 5233330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 5247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis if (mProtectedByApp) { 52516f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten // need a hardware-protected path to external video sink 52616f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten usage |= GraphicBuffer::USAGE_PROTECTED; 52716f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten } 5283330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 5293330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 5303330b203039dea366d4981db1408a460134b2d2cMathias Agopian 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 537a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian (front.requested_h != temp.requested_h); 538a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 539a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 540cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 542a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 543a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian this, 544a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(temp.requested_w), int(temp.requested_h), 545a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(front.requested_w), int(front.requested_h)); 546a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 547a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!isFixedSize()) { 548a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // we're being resized and there is a freeze display request, 549a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // acquire a freeze lock, so that the screen stays put 550a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // until we've redrawn at the new size; this is to avoid 551a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // glitches upon orientation changes. 552a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (mFlinger->hasFreezeRequest()) { 553a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // if the surface is hidden, don't try to acquire the 554a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // freeze lock, since hidden surfaces may never redraw 555a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 556a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 559caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // the drawing state's size 562a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Layer::State& editDraw(mDrawingState); 563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_w = temp.requested_w; 564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_h = temp.requested_h; 565df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 566a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size, form this point on, when the client request 567a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // a buffer, it'll get the new size. 568a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 5696656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 571b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 57396f0819f81293076e652792794a961543e6750d7Mathias Agopian // all buffers need reallocation 57496f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->reallocateAll(); 57596f0819f81293076e652792794a961543e6750d7Mathias Agopian } 576a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } else { 577a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size 578a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 579a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 581cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 593a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 594cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 595cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 596cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 597733189d408e13b54fd70971b265244367efd0f51Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 600a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const { 601a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mLock); 602a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mFixedSize; 603a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 604a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 611b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 612b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 613b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (!lcblk) { 61496f0819f81293076e652792794a961543e6750d7Mathias Agopian // client died 61596f0819f81293076e652792794a961543e6750d7Mathias Agopian recomputeVisibleRegions = true; 61696f0819f81293076e652792794a961543e6750d7Mathias Agopian return; 61796f0819f81293076e652792794a961543e6750d7Mathias Agopian } 61896f0819f81293076e652792794a961543e6750d7Mathias Agopian 619cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf == NOT_ENOUGH_DATA) { 621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // NOTE: This is not an error, it simply means there is nothing to 622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // retire. The buffer is locked because we will use it 623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 626d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf < NO_ERROR) { 628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 629d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 630d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 631d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 632d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 634da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 635da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); 636ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold const bool activeBlending = 637ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer()); 638ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 639d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 640b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 641d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mPostedDirtyRegion.clear(); 642d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return; 643d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 645da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian if (noActiveBuffer) { 646da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // we didn't have an active buffer, we need to recompute 647da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian // our visible region 648da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian recomputeVisibleRegions = true; 649da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian } 650da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6513330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 652d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 653ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) { 654ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // new buffer has different opacity than previous active buffer, need 655ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold // to recompute visible regions accordingly 656ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold recomputeVisibleRegions = true; 657ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 658ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 659b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the dirty region 660d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 661d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 662d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 663d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 664d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 665d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 666d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 667d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 668df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 669d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 670d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 671d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 672d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 673d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 674d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 675d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 676d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 677d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 678d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 679d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 680d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 681d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 682d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 683d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 684d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 685d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 686d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 687d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 688d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 689d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 690d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 6918f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 692d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 693d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 694d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 695b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 696b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the crop region 697b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian setBufferCrop( lcblk->getCrop(buf) ); 698b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 699b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian // get the transformation 700b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian setBufferTransform( lcblk->getTransform(buf) ); 701b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian 702d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 703d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 704d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 705d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 706d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 707d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 708caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 709caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 710e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 711e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 712e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 713e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 715245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 716245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 717245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 718245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 719245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * for instance, a degenerate case could be that the user did an empty 720245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * update but repainted the buffer with appropriate content (after a 721245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * resize for instance). 722245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian */ 723245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian reloadTexture( mPostedDirtyRegion ); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 745c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 746c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 7471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian // (because it may never be updated and therefore never release it) 748c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 749c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 7531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 7541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 757b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 758b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian uint32_t totalTime = 0; 759b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lcblk) { 760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 761b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian totalTime= stats.totalTime; 762b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result.append( lcblk->dump(" ") ); 763b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 764b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 7651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 7661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 7671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w0=0, h0=0, s0=0; 7681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w1=0, h1=0, s1=0; 7691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 7731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf1 != 0) { 7751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w1 = buf1->getWidth(); 7761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h1 = buf1->getHeight(); 7771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s1 = buf1->getStride(); 7781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 7811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 7821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mFormat, w0, h0, s0, w1, h1, s1, 784b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian getFreezeLock().get(), totalTime); 7851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 7871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 7881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 789076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 790076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::ClientRef() 792579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian : mControlBlock(0), mToken(-1) { 793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 794b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 795b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::~ClientRef() { 796b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 798b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::ClientRef::getToken() const { 799b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mLock); 800b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mToken; 801b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 802b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 803579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const { 804579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian Mutex::Autolock _l(mLock); 805579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return mUserClient.promote(); 806579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 807579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 808b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 809579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const sp<SharedBufferServer>& sharedClient, int32_t token) { 810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mLock); 811579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 812579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian { // scope for strong mUserClient reference 813579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<UserClient> userClient(mUserClient.promote()); 814579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (mUserClient != 0 && mControlBlock != 0) { 815579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock->setStatus(NO_INIT); 816579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 817579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 818579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 819b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mUserClient = uc; 820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mToken = token; 821579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock = sharedClient; 822b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 823b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 824b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 825b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 826b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mUserClient.promote(); 827b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 828b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 829b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// this class gives us access to SharedBufferServer safely 830b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// it makes sure the UserClient (and its associated shared memory) 831b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// won't go away while we're accessing it. 832b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref) 833579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian : mControlBlock(0) 834b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 835b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(ref.mLock); 836b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mUserClientStrongRef = ref.mUserClient.promote(); 837b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mUserClientStrongRef != 0) 838579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mControlBlock = ref.mControlBlock; 839579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 840579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 841579b3f88d03d06b897b778bd11818f5104677d1dMathias AgopianLayer::ClientRef::Access::~Access() 842579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 843b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 844b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 845b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 846b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 847d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 848bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 849420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex(-1), mFailover(false) 850bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 851bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 852bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 853bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager() 854d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 855d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 856d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 85754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennisstatus_t Layer::BufferManager::resize(size_t size, 85854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis const sp<SurfaceFlinger>& flinger, EGLDisplay dpy) 859bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 860bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 86154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 86254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis if (size < mNumBuffers) { 86354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Move the active texture into slot 0 864420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian BufferData activeBufferData = mBufferData[mActiveBufferIndex]; 865420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mBufferData[mActiveBufferIndex] = mBufferData[0]; 86654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[0] = activeBufferData; 867420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex = 0; 86854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 86954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Free the buffers that are no longer needed. 87054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis for (size_t i = size; i < mNumBuffers; i++) { 87154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].buffer = 0; 87254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 87354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Create a message to destroy the textures on SurfaceFlinger's GL 87454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // thread. 87554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis class MessageDestroyTexture : public MessageBase { 87654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis Image mTexture; 87754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis EGLDisplay mDpy; 87854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis public: 87954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis MessageDestroyTexture(const Image& texture, EGLDisplay dpy) 88054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis : mTexture(texture), mDpy(dpy) { } 88154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis virtual bool handler() { 88254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis status_t err = Layer::BufferManager::destroyTexture( 88354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis &mTexture, mDpy); 88454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis LOGE_IF(err<0, "error destroying texture: %d (%s)", 88554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mTexture.name, strerror(-err)); 88654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis return true; // XXX: err == 0; ???? 88754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 88854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis }; 88954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 89054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis MessageDestroyTexture *msg = new MessageDestroyTexture( 89154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture, dpy); 89254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 89354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Don't allow this texture to be cleaned up by 89454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // BufferManager::destroy. 89554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture.name = -1U; 89654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis mBufferData[i].texture.image = EGL_NO_IMAGE_KHR; 89754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 89854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis // Post the message to the SurfaceFlinger object. 89954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis flinger->postMessageAsync(msg); 90054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 90154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis } 90254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis 903bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mNumBuffers = size; 904bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 905d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 906d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 907d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging 908d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 909d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mBufferData[index].buffer; 910d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 911d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 912d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 913420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian BufferData const * const buffers = mBufferData; 914420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian Mutex::Autolock _l(mLock); 915420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBuffer = buffers[index].buffer; 916420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian mActiveBufferIndex = index; 917d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 918d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 919d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 920d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 921420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBufferIndex; 922d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 923d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 924d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 925bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Texture res; 926420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian if (mFailover || mActiveBufferIndex<0) { 927bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian res = mFailoverTexture; 928bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else { 929420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture; 930bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 931bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 932d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 933d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 934d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 935420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBuffer; 936d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 937d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 938da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopianbool Layer::BufferManager::hasActiveBuffer() const { 939420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian return mActiveBufferIndex >= 0; 940da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian} 941da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 942d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 943d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 944bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 945d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer; 946d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 947bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffer = buffers[index].buffer; 948bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = 0; 949d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return buffer; 950d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 951d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 952d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 953d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 954d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 955bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 956d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 957bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = buffer; 958bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].texture.dirty = true; 959d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 960d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 961d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 962d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 963d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 964bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 965bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian size_t num; 966bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian { // scope for the lock 967bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 968bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian num = mNumBuffers; 969bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 970bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[i].buffer = 0; 971bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 972bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 973bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 974bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 975d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 976d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 977d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 978d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 979d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 980d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 981d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 982d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 983b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t err = NO_INIT; 984420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian ssize_t index = mActiveBufferIndex; 985b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (index >= 0) { 9861f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (!mFailover) { 9871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian Image& texture(mBufferData[index].texture); 9881f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian err = mTextureManager.initEglImage(&texture, dpy, buffer); 9891f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 9901f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // free all resources associated with using EGLImages. 9911f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (err == NO_ERROR) { 9921f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mFailover = false; 9931f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 9941f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } else { 9951f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mFailover = true; 9961f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian const size_t num = mNumBuffers; 9971f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian for (size_t i=0 ; i<num ; i++) { 9981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 9991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 1000e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber } 10011f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } else { 10021f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian // we failed once, don't try again 10031f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian err = BAD_VALUE; 1004d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 1005d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 1006d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return err; 1007d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 1008d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 1009d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture( 1010d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const Region& dirty, const GGLSurface& t) 1011d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 1012d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 1013d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 1014d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 1015bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 1016bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 1017bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->name != -1U) { 1018bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian glDeleteTextures(1, &tex->name); 1019bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->name = -1U; 1020bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 1021bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 1022bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 1023bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 1024bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 1025bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 1026bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 1027bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1028d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// --------------------------------------------------------------------------- 1029d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 10309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 103196f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Layer>& owner) 103296f0819f81293076e652792794a961543e6750d7Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 10339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 10349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 10359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 10369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 1037076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 1038076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 1039076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 1040a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 1041a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 1042076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 10433330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 1044076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 1045076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 1046bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 1047bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * requestBuffer() cannot be called from the main thread 1048bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 1049bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 1050bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 1051a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 1052076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 1053076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 1054076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1056b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 1057b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 1058b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian status_t err = DEAD_OBJECT; 1059b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Layer> owner(getOwner()); 1060b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (owner != 0) { 1061bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 1062bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * setBufferCount() cannot be called from the main thread 1063bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 1064bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 1065bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 1066b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian err = owner->setBufferCount(bufferCount); 1067b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 1068b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 1069b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 1070b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 1075