Layer.cpp revision 96f0819f81293076e652792794a961543e6750d7
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" 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopiantemplate <typename T> inline T min(T a, T b) { 45ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return a<b ? a : b; 46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian} 47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5096f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, 5196f0819f81293076e652792794a961543e6750d7Mathias Agopian DisplayID display, const sp<Client>& client) 5296f0819f81293076e652792794a961543e6750d7Mathias Agopian : LayerBaseClient(flinger, display, client), 53d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian lcblk(NULL), 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecure(false), 55401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsBlending(true), 56d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mNeedsDithering(false), 57d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mTextureManager(mFlags), 58a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager(mTextureManager), 59a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mWidth(0), mHeight(0), mFixedSize(false) 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 65bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // FIXME: must be called from the main UI thread 66bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 67bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 68bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the actual buffers will be destroyed here 70d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian delete lcblk; 71d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 72d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 7396f0819f81293076e652792794a961543e6750d7Mathias Agopian// TODO: get rid of this 7496f0819f81293076e652792794a961543e6750d7Mathias Agopianvoid Layer::setToken(int32_t token) 7596f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 7696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> ourClient(client.promote()); 7796f0819f81293076e652792794a961543e6750d7Mathias Agopian 7896f0819f81293076e652792794a961543e6750d7Mathias Agopian mToken = token; 7996f0819f81293076e652792794a961543e6750d7Mathias Agopian 8096f0819f81293076e652792794a961543e6750d7Mathias Agopian // no OpenGL operation is possible here, since we might not be 8196f0819f81293076e652792794a961543e6750d7Mathias Agopian // in the OpenGL thread. 8296f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk = new SharedBufferServer( 8396f0819f81293076e652792794a961543e6750d7Mathias Agopian ourClient->ctrlblk, token, mBufferManager.getDefaultBufferCount(), 8496f0819f81293076e652792794a961543e6750d7Mathias Agopian getIdentity()); 8596f0819f81293076e652792794a961543e6750d7Mathias Agopian 8696f0819f81293076e652792794a961543e6750d7Mathias Agopian mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() ); 8796f0819f81293076e652792794a961543e6750d7Mathias Agopian} 8896f0819f81293076e652792794a961543e6750d7Mathias Agopian 89d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 91d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 92d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 9396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> ourClient(client.promote()); 9496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (ourClient != 0) { 9596f0819f81293076e652792794a961543e6750d7Mathias Agopian // wake up the condition 9696f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->setStatus(NO_INIT); 9796f0819f81293076e652792794a961543e6750d7Mathias Agopian } 9848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 99cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSurface; 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch() 1069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 107bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: Called from the main UI thread 108bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 110f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 111bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 112bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 113bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 114bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mSurface.clear(); 115bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 116bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 117bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mWidth = mHeight = 0; 1189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 1199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 121f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 124401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 129401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 130401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 131ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 132ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 133ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 134ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 135ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 136ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 137ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 138ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 139ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 140401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 141401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 142a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 143a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 145ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mWidth = w; 146cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 1473330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 149ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 150401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // we use the red index 151401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 152401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 153401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 154401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 15596f0819f81293076e652792794a961543e6750d7Mathias Agopian mSurface = new SurfaceLayer(mFlinger, this); 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 1628f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian if (buffer == NULL) { 1638f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // this situation can happen if we ran out of memory for instance. 1648f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // not much we can do. continue to use whatever texture was bound 1658f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // to this context. 1668f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian return; 1678f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian } 1688f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 16954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer 17057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mFlags & DisplayHardware::DIRECT_TEXTURE) { 171d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 172d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 173d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // not sure what we can do here... 174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 175d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian goto slowpath; 176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 17754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else 17854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif 17954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian { 180fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath: 181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GGLSurface t; 1823330b203039dea366d4981db1408a460134b2d2cMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 1830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 1840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian res, strerror(res), buffer.get()); 1850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (res == NO_ERROR) { 186d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mBufferManager.loadTexture(dirty, t); 1870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian buffer->unlock(); 188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 194d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Texture tex(mBufferManager.getActiveTexture()); 195d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (tex.name == -1LU) { 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 197179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 198179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 199179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 200179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 201179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 202179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 203179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 204179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 205179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 206179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 207179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 208179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 209179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 210179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 211179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 212179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian under.orSelf(layer->visibleRegionScreen); 213179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 214179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 215179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 216179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 217179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian clearWithOpenGL(holes); 218179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 221d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian drawWithOpenGL(clip, tex); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 224a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const 225a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 226a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 227a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // NOTE: there is a race here, because mFixedSize is updated in a 228a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // binder transaction. however, it doesn't really matter since it is 229a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // evaluated each time we draw. To be perfectly correct, this flag 230a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // would have to be associated with a buffer. 231a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (mFixedSize) 232a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return true; 233a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 234a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return LayerBase::needsFiltering(); 235a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 236a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 237b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 238b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 239b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 240bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // Ensures our client doesn't go away while we're accessing 241b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // the shared area. 242b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Client> ourClient(client.promote()); 243b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (ourClient == 0) { 244b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // oops, the client is already gone 245b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return DEAD_OBJECT; 246b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 247b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 248bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 249bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t err = lcblk->resize(bufferCount); 250bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (err == NO_ERROR) 251bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.resize(bufferCount); 252b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 253b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 254b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 255b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 256a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 257a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 258a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t usage) 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2603330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 26148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 262a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((reqWidth | reqHeight | reqFormat) < 0) 263a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 264a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 265a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 266a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 267a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 26848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 26948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 27048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian sp<Client> ourClient(client.promote()); 27148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (ourClient == 0) { 27248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 27348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 27448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 27548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 276076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 277cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 278cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 279cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 280bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * 281cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 282cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 283cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer cannot become the front buffer under our feet, since we're called 284cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * from Surface::dequeue() 285076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 286cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->assertReallocate(index); 287cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 28848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err != NO_ERROR) { 28948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the surface may have died 29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 29148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 29248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 293a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, h, f; 29448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 29548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 296a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); 297a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool formatChanged = mReqFormat != reqFormat; 298a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqWidth = reqWidth; 299a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqHeight = reqHeight; 300a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqFormat = reqFormat; 301a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFixedSize = reqWidth && reqHeight; 302a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian w = reqWidth ? reqWidth : mWidth; 303a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian h = reqHeight ? reqHeight : mHeight; 304a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian f = reqFormat ? reqFormat : mFormat; 305d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian buffer = mBufferManager.detachBuffer(index); 306a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (fixedSizeChanged || formatChanged) { 307a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian lcblk->reallocateAllExcept(index); 308a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 30948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 31048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 3113330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 3126d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 313a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian err = buffer->reallocate(w, h, f, effectiveUsage); 314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 315cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // here we have to reallocate a new buffer because we could have a 316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // client in our process with a reference to it (eg: status bar), 317cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // and we can't release the handle under its feet. 318cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer.clear(); 319a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 320cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = buffer->initCheck(); 321076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 322cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 323cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 324cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 326cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 3297e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 3307e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 333cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 33448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 335a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager.attachBuffer(index, buffer); 336f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 338f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 339f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 3403330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3413330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 3423330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 3433330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 3443330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3453330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3463330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 3473330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3483330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3493330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3503330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3513330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3543330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 3553330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 3563330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3573330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3583330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3593330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 3603330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 36189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian // request EGLImage for all buffers 36289141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 3663330b203039dea366d4981db1408a460134b2d2cMathias Agopian 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 372a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 373a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian (front.requested_h != temp.requested_h); 374a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 375a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 376cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 379a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian this, 380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(temp.requested_w), int(temp.requested_h), 381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(front.requested_w), int(front.requested_h)); 382a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 383a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!isFixedSize()) { 384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // we're being resized and there is a freeze display request, 385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // acquire a freeze lock, so that the screen stays put 386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // until we've redrawn at the new size; this is to avoid 387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // glitches upon orientation changes. 388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (mFlinger->hasFreezeRequest()) { 389a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // if the surface is hidden, don't try to acquire the 390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // freeze lock, since hidden surfaces may never redraw 391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 392a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 393a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 395caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 396a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // the drawing state's size 398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Layer::State& editDraw(mDrawingState); 399a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_w = temp.requested_w; 400a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_h = temp.requested_h; 401df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 402a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size, form this point on, when the client request 403a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // a buffer, it'll get the new size. 404a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 4056656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 40696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> ourClient(client.promote()); 40796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (ourClient != 0) { 40896f0819f81293076e652792794a961543e6750d7Mathias Agopian // all buffers need reallocation 40996f0819f81293076e652792794a961543e6750d7Mathias Agopian lcblk->reallocateAll(); 41096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 411a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } else { 412a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size 413a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 414a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 429cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 430cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 431cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 434a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const { 435a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mLock); 436a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mFixedSize; 437a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 438a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 44596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> ourClient(client.promote()); 44696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (ourClient == 0) { 44796f0819f81293076e652792794a961543e6750d7Mathias Agopian // client died 44896f0819f81293076e652792794a961543e6750d7Mathias Agopian recomputeVisibleRegions = true; 44996f0819f81293076e652792794a961543e6750d7Mathias Agopian return; 45096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 45196f0819f81293076e652792794a961543e6750d7Mathias Agopian 452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 453d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf == NOT_ENOUGH_DATA) { 454d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // NOTE: This is not an error, it simply means there is nothing to 455d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // retire. The buffer is locked because we will use it 456cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 459d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 460d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf < NO_ERROR) { 461d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 462d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 463d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 464d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 465d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 466cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 467d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 468d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 469d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mPostedDirtyRegion.clear(); 470d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return; 471d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // get the dirty region 4743330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 484df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 485d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 498d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 5078f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 513d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 517caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 518caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 519e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 520e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 521e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 522e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 524245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 525245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 526245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 527245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 528245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * for instance, a degenerate case could be that the user did an empty 529245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * update but repainted the buffer with appropriate content (after a 530245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * resize for instance). 531245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian */ 532245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian reloadTexture( mPostedDirtyRegion ); 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 554c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 555c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 5561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian // (because it may never be updated and therefore never release it) 557c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 558c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip() 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 56396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> ourClient(client.promote()); 56496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (ourClient != 0) { 56596f0819f81293076e652792794a961543e6750d7Mathias Agopian int buf = mBufferManager.getActiveBufferIndex(); 56696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = lcblk->unlock( buf ); 56796f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf); 56896f0819f81293076e652792794a961543e6750d7Mathias Agopian } 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 5731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 5741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 5751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 5771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append( lcblk->dump(" ") ); 5781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 5791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 5801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w0=0, h0=0, s0=0; 5811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w1=0, h1=0, s1=0; 5821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 5831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 5841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 5851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 5861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf1 != 0) { 5881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w1 = buf1->getWidth(); 5891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h1 = buf1->getHeight(); 5901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s1 = buf1->getStride(); 5911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 5931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 5941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 5951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 5961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian pixelFormat(), 5971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0, h0, s0, w1, h1, s1, 5981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian getFreezeLock().get(), stats.totalTime); 5991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 6001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 6011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 6021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 605d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 606bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 607bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mActiveBuffer(0), mFailover(false) 608bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 609bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 610bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 611bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager() 612d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 613d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 614d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 615bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size) 616bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 617bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 618bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mNumBuffers = size; 619bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging 623d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 624d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mBufferData[index].buffer; 625d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 626d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 628d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // TODO: need to validate 'index' 629d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mActiveBuffer = index; 630d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 631d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 632d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 633d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 634d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mActiveBuffer; 635d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 637d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 638bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Texture res; 639bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (mFailover) { 640bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian res = mFailoverTexture; 641bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else { 642bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 643bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 644bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 645d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 646d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 647d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 648bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian const size_t activeBuffer = mActiveBuffer; 649bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData const * const buffers = mBufferData; 650d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 651bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return buffers[activeBuffer].buffer; 652d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 653d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 654d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 655d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 656bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 657d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer; 658d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 659bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffer = buffers[index].buffer; 660bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = 0; 661d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return buffer; 662d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 663d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 664d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 665d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 666d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 667bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 668d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 669bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = buffer; 670bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].texture.dirty = true; 671d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 672d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 673d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 674d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 675d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 676bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 677bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian size_t num; 678bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian { // scope for the lock 679bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian num = mNumBuffers; 681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 682bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[i].buffer = 0; 683bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 684bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 685bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 686bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 687d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 688d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 691d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 692d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 693d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 694d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 695d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian size_t index = mActiveBuffer; 696bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Image& texture(mBufferData[index].texture); 697d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian status_t err = mTextureManager.initEglImage(&texture, dpy, buffer); 698d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 699d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // free all resources associated with using EGLImages. 700d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (err == NO_ERROR) { 701d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFailover = false; 702d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 703d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } else { 704d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFailover = true; 705bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian const size_t num = mNumBuffers; 706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 709d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 710d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return err; 711d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 712d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 713d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture( 714d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const Region& dirty, const GGLSurface& t) 715d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 716d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 717d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 718d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 719bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 720bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 721bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->name != -1U) { 722bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian glDeleteTextures(1, &tex->name); 723bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->name = -1U; 724bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 725bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 726bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 727bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 728bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 729bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 730bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 731bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 732d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// --------------------------------------------------------------------------- 733d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 7349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 73596f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Layer>& owner) 73696f0819f81293076e652792794a961543e6750d7Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 7379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 7389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 7399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 7409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 744a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 745a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 7473330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 750bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 751bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * requestBuffer() cannot be called from the main thread 752bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 753bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 754bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 755a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 757076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 760b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 761b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian status_t err = DEAD_OBJECT; 763b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Layer> owner(getOwner()); 764b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (owner != 0) { 765bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 766bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * setBufferCount() cannot be called from the main thread 767bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 768bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 769bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 770b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian err = owner->setBufferCount(bufferCount); 771b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 772b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 773b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 774b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 779