Layer.cpp revision a7f669256f93a593c723f05784ef04d3c7d052bb
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 50cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display, 51d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<Client>& client, int32_t i) 52d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian : LayerBaseClient(flinger, display, client, i), 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 // no OpenGL operation is possible here, since we might not be 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the OpenGL thread. 63d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian lcblk = new SharedBufferServer( 64bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian client->ctrlblk, i, mBufferManager.getDefaultBufferCount(), 65d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian getIdentity()); 66d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 67d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() ); 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // FIXME: must be called from the main UI thread 73bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 74bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 75bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the actual buffers will be destroyed here 77d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian delete lcblk; 78d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 81d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 82d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 83d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 84d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // wake up the condition 85d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian lcblk->setStatus(NO_INIT); 8648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 87cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSurface; 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch() 949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 95bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: Called from the main UI thread 96bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 98f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 99bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 100bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 101bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.destroy(dpy); 102bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mSurface.clear(); 103bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 104bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 105bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mWidth = mHeight = 0; 1069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 1079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 109f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 112401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 118401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 119ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 120ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 121ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 122ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 123ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 124ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 125ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 126ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 127ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 128401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 129401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 130a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 131a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 132cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 133ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mWidth = w; 134cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 1353330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 137ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 138401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // we use the red index 139401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 140401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 141401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 142401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 1439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 149d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 1508f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian if (buffer == NULL) { 1518f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // this situation can happen if we ran out of memory for instance. 1528f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // not much we can do. continue to use whatever texture was bound 1538f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // to this context. 1548f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian return; 1558f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian } 1568f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 15754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer 15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mFlags & DisplayHardware::DIRECT_TEXTURE) { 159d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 160d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // not sure what we can do here... 162d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 163d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian goto slowpath; 164076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 16554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else 16654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif 16754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian { 168fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath: 169076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GGLSurface t; 1703330b203039dea366d4981db1408a460134b2d2cMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 1710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 1720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian res, strerror(res), buffer.get()); 1730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (res == NO_ERROR) { 174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mBufferManager.loadTexture(dirty, t); 1750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian buffer->unlock(); 176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 182d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Texture tex(mBufferManager.getActiveTexture()); 183d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (tex.name == -1LU) { 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 185179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 186179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 187179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 188179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 189179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 190179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 191179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 192179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 193179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 194179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 195179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 196179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 197179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 198179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 199179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 200179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian under.orSelf(layer->visibleRegionScreen); 201179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 202179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 203179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 204179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 205179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian clearWithOpenGL(holes); 206179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 209d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian drawWithOpenGL(clip, tex); 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 212a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const 213a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 214a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 215a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // NOTE: there is a race here, because mFixedSize is updated in a 216a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // binder transaction. however, it doesn't really matter since it is 217a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // evaluated each time we draw. To be perfectly correct, this flag 218a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian // would have to be associated with a buffer. 219a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian if (mFixedSize) 220a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return true; 221a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 222a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian return LayerBase::needsFiltering(); 223a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 224a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 225b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 226b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 227b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 228bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // Ensures our client doesn't go away while we're accessing 229b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // the shared area. 230b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Client> ourClient(client.promote()); 231b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (ourClient == 0) { 232b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // oops, the client is already gone 233b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return DEAD_OBJECT; 234b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 235b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 236bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 237bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t err = lcblk->resize(bufferCount); 238bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (err == NO_ERROR) 239bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mBufferManager.resize(bufferCount); 240b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 241b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 242b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 243b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 244a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 245a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 246a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t usage) 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2483330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 24948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 250a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((reqWidth | reqHeight | reqFormat) < 0) 251a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 252a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 253a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 254a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return buffer; 255a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 25648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 25748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 25848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian sp<Client> ourClient(client.promote()); 25948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (ourClient == 0) { 26048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 26148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 26248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 26348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 264076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 265cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 266cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 267cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 268bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * 269cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 270cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 271cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer cannot become the front buffer under our feet, since we're called 272cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * from Surface::dequeue() 273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 274cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->assertReallocate(index); 275cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 27648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err != NO_ERROR) { 27748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the surface may have died 27848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 27948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 28048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 281a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, h, f; 28248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 28348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 284a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); 285a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool formatChanged = mReqFormat != reqFormat; 286a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqWidth = reqWidth; 287a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqHeight = reqHeight; 288a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mReqFormat = reqFormat; 289a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFixedSize = reqWidth && reqHeight; 290a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian w = reqWidth ? reqWidth : mWidth; 291a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian h = reqHeight ? reqHeight : mHeight; 292a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian f = reqFormat ? reqFormat : mFormat; 293d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian buffer = mBufferManager.detachBuffer(index); 294a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (fixedSizeChanged || formatChanged) { 295a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian lcblk->reallocateAllExcept(index); 296a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 29748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 29848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 2993330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 3006d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 301a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian err = buffer->reallocate(w, h, f, effectiveUsage); 302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 303cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // here we have to reallocate a new buffer because we could have a 304cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // client in our process with a reference to it (eg: status bar), 305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // and we can't release the handle under its feet. 306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer.clear(); 307a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 308cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = buffer->initCheck(); 309076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 310cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 311cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 312cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 313cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 3177e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 3187e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 321cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 32248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 323a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferManager.attachBuffer(index, buffer); 324f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 326f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 327f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 3283330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3293330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 3303330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 3313330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3333330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3343330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 3353330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3363330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3373330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3383330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3393330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3403330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 3413330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3423330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 3433330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 3443330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3453330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3463330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3473330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 3483330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 34989141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian // request EGLImage for all buffers 35089141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 3513330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 3543330b203039dea366d4981db1408a460134b2d2cMathias Agopian 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 360a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 361a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian (front.requested_h != temp.requested_h); 362a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 363a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 364cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 366a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 367a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian this, 368a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(temp.requested_w), int(temp.requested_h), 369a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int(front.requested_w), int(front.requested_h)); 370a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 371a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!isFixedSize()) { 372a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // we're being resized and there is a freeze display request, 373a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // acquire a freeze lock, so that the screen stays put 374a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // until we've redrawn at the new size; this is to avoid 375a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // glitches upon orientation changes. 376a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (mFlinger->hasFreezeRequest()) { 377a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // if the surface is hidden, don't try to acquire the 378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // freeze lock, since hidden surfaces may never redraw 379a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 383caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // the drawing state's size 386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Layer::State& editDraw(mDrawingState); 387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_w = temp.requested_w; 388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian editDraw.requested_h = temp.requested_h; 389df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size, form this point on, when the client request 391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // a buffer, it'll get the new size. 392a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 3936656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 394a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // all buffers need reallocation 395a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian lcblk->reallocateAll(); 396a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } else { 397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // record the new size 398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 399a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 401cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 413a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 414cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 415cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 419a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const { 420a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mLock); 421a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mFixedSize; 422a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 430cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 431d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf == NOT_ENOUGH_DATA) { 432d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // NOTE: This is not an error, it simply means there is nothing to 433d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // retire. The buffer is locked because we will use it 434cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 437d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 438d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (buf < NO_ERROR) { 439d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 440d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 441d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 442d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 443d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 445d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 446d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 447d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mPostedDirtyRegion.clear(); 448d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return; 449d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 451cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // get the dirty region 4523330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 453d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 454d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 455d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 456d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 457d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 458d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 459d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 460d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 461d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 462df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 463d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 464d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 465d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 466d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 467d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 468d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 469d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 470d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 471d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 472d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 473d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 474d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 484d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 4858f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 495caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 496caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 497e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 498e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 499e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 500e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 502245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 503245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 504245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 505245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 506245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * for instance, a degenerate case could be that the user did an empty 507245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * update but repainted the buffer with appropriate content (after a 508245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * resize for instance). 509245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian */ 510245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian reloadTexture( mPostedDirtyRegion ); 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 532c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 533c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 5341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian // (because it may never be updated and therefore never release it) 535c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 536c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip() 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 541d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian int buf = mBufferManager.getActiveBufferIndex(); 542d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian status_t err = lcblk->unlock( buf ); 543d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf); 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 5481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 5491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 5501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 5521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append( lcblk->dump(" ") ); 5531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 5541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 5551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w0=0, h0=0, s0=0; 5561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w1=0, h1=0, s1=0; 5571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 5581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 5591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 5601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 5611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf1 != 0) { 5631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w1 = buf1->getWidth(); 5641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h1 = buf1->getHeight(); 5651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s1 = buf1->getStride(); 5661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 5681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 5691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 5701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 5711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian pixelFormat(), 5721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0, h0, s0, w1, h1, s1, 5731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian getFreezeLock().get(), stats.totalTime); 5741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 5761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 5771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 580d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 581bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 582bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mActiveBuffer(0), mFailover(false) 583bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 584bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 585bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 586bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager() 587d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 588d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 589d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 590bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size) 591bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 592bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 593bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian mNumBuffers = size; 594bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 595d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 596d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 597d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging 598d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 599d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mBufferData[index].buffer; 600d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 601d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 602d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 603d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // TODO: need to validate 'index' 604d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mActiveBuffer = index; 605d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 606d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 607d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 608d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 609d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mActiveBuffer; 610d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 611d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 612d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 613bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Texture res; 614bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (mFailover) { 615bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian res = mFailoverTexture; 616bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else { 617bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 618bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 619bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 623bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian const size_t activeBuffer = mActiveBuffer; 624bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData const * const buffers = mBufferData; 625d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 626bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return buffers[activeBuffer].buffer; 627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 628d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 629d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 630d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 631bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 632d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sp<GraphicBuffer> buffer; 633d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 634bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffer = buffers[index].buffer; 635bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = 0; 636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return buffer; 637d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 638d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 639d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 640d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 641d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 642bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 643d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Mutex::Autolock _l(mLock); 644bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].buffer = buffer; 645bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[index].texture.dirty = true; 646d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 647d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 648d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 649d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 650d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 651bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian BufferData* const buffers = mBufferData; 652bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian size_t num; 653bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian { // scope for the lock 654bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Mutex::Autolock _l(mLock); 655bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian num = mNumBuffers; 656bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 657bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian buffers[i].buffer = 0; 658bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 659bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 660bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 661bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 662d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 663d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 664d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return NO_ERROR; 665d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 666d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 667d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 668d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const sp<GraphicBuffer>& buffer) 669d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 670d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian size_t index = mActiveBuffer; 671bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Image& texture(mBufferData[index].texture); 672d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian status_t err = mTextureManager.initEglImage(&texture, dpy, buffer); 673d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 674d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian // free all resources associated with using EGLImages. 675d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (err == NO_ERROR) { 676d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFailover = false; 677d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mFailoverTexture, dpy); 678d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } else { 679d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mFailover = true; 680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian const size_t num = mNumBuffers; 681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian for (size_t i=0 ; i<num ; i++) { 682d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 683d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 684d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 685d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return err; 686d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 687d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 688d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture( 689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian const Region& dirty, const GGLSurface& t) 690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 691d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 692d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 693d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 694bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 695bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 696bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->name != -1U) { 697bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian glDeleteTextures(1, &tex->name); 698bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->name = -1U; 699bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 700bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 701bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 702bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 703bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 704bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return NO_ERROR; 705bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// --------------------------------------------------------------------------- 708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 7099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 7109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian SurfaceID id, const sp<Layer>& owner) 7119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 7129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 7139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 7149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 7159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 716076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 717076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 718076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 719a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 720a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 721076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 7223330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 723076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 724076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 725bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 726bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * requestBuffer() cannot be called from the main thread 727bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 728bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 729bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 730a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 735b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 736b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 737b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian status_t err = DEAD_OBJECT; 738b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<Layer> owner(getOwner()); 739b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (owner != 0) { 740bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* 741bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * setBufferCount() cannot be called from the main thread 742bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * as it could cause a dead-lock, since it may have to wait 743bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian * on conditions updated my the main thread. 744bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian */ 745b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian err = owner->setBufferCount(bufferCount); 746b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 747b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 748b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 749b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 754