Layer.cpp revision 1b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8
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, 51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian const sp<Client>& c, int32_t i) 5248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian : LayerBaseClient(flinger, display, c, i), 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecure(false), 54a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian mNoEGLImageForSwBuffers(false), 55401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsBlending(true), 56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering(false) 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // no OpenGL operation is possible here, since we might not be 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the OpenGL thread. 60cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFrontBufferIndex = lcblk->getFrontBuffer(); 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian destroy(); 660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the actual buffers will be destroyed here 6748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 68cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopianvoid Layer::destroy() 700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian{ 71cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mTextures[i].name != -1U) { 73550b79f4491909b0f223d8fb25155974f53b3f79Mathias Agopian glDeleteTextures(1, &mTextures[i].name); 740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian mTextures[i].name = -1U; 75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mTextures[i].image != EGL_NO_IMAGE_KHR) { 77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian eglDestroyImageKHR(dpy, mTextures[i].image); 790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 8148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 82cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mBuffers[i].clear(); 8348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mWidth = mHeight = 0; 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 858c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian mSurface.clear(); 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 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{ 950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 96f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 978c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian destroy(); 989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 101f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 104401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 110401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 111ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 112ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 113ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 114ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 115ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 116ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 117ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 118ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 119ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 120401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 121401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 122a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 123a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 124cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 125ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mWidth = w; 126cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 1273330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 129a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS); 130ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 131401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // we use the red index 132401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 133401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 134401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 135401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 136cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 1373330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBuffers[i] = new GraphicBuffer(); 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 145cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 1469ec430adaea1cb88eaa1e78c7f759cd42ab6cf7aMathias Agopian sp<GraphicBuffer> buffer(getFrontBufferLocked()); 1478f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian if (buffer == NULL) { 1488f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // this situation can happen if we ran out of memory for instance. 1498f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // not much we can do. continue to use whatever texture was bound 1508f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // to this context. 1518f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian return; 1528f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian } 1538f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 1548f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian const int index = mFrontBufferIndex; 15557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 15657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian // create the new texture name if needed 15757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (UNLIKELY(mTextures[index].name == -1U)) { 15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].name = createTexture(); 15957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].width = 0; 16057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].height = 0; 16157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 16257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 16354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer 16457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mFlags & DisplayHardware::DIRECT_TEXTURE) { 16557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) { 16657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mTextures[index].dirty) { 167fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) { 168fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian // not sure what we can do here... 169fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 170fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian goto slowpath; 171fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian } 17257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 173076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else { 17457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width || 17557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer->height != buffer->height)) { 17657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer.clear(); 17757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer = new GraphicBuffer( 17857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buffer->width, buffer->height, buffer->format, 17957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN | 18057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GraphicBuffer::USAGE_HW_TEXTURE); 181fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian if (initializeEglImage( 182fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mHybridBuffer, &mTextures[0]) != NO_ERROR) { 183fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian // not sure what we can do here... 184fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 185fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mHybridBuffer.clear(); 186fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian goto slowpath; 187fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian } 188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 189076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 19057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GGLSurface t; 19157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 19257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 19357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian res, strerror(res), buffer.get()); 19457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (res == NO_ERROR) { 19557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian Texture* const texture(&mTextures[0]); 19657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 19757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian glBindTexture(GL_TEXTURE_2D, texture->name); 19857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 19957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian sp<GraphicBuffer> buf(mHybridBuffer); 20057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian void* vaddr; 20157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr); 20257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (res == NO_ERROR) { 20357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian int bpp = 0; 20457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian switch (t.format) { 20554ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGB_565: 20654ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBA_4444: 20757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bpp = 2; 20857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian break; 20954ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 21054ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBX_8888: 21157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bpp = 4; 21257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian break; 21357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian default: 21454ed4f6282bdea251455f39b978626026affdbefMathias Agopian if (isSupportedYuvFormat(t.format)) { 21554ed4f6282bdea251455f39b978626026affdbefMathias Agopian // just show the Y plane of YUV buffers 21654ed4f6282bdea251455f39b978626026affdbefMathias Agopian bpp = 1; 21754ed4f6282bdea251455f39b978626026affdbefMathias Agopian break; 21854ed4f6282bdea251455f39b978626026affdbefMathias Agopian } 21957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian // oops, we don't handle this format! 22057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian LOGE("layer %p, texture=%d, using format %d, which is not " 22157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian "supported by the GL", this, texture->name, t.format); 22257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 22357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (bpp) { 22457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian const Rect bounds(dirty.getBounds()); 22557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t src_stride = t.stride; 22657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t dst_stride = buf->stride; 22757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (src_stride == dst_stride && 22857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bounds.width() == t.width && 22957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bounds.height() == t.height) 23057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian { 23157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian memcpy(vaddr, t.data, t.height * t.stride * bpp); 23257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } else { 23357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GLubyte const * src = t.data + 23457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian (bounds.left + bounds.top * src_stride) * bpp; 23557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GLubyte * dst = (GLubyte *)vaddr + 23657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian (bounds.left + bounds.top * dst_stride) * bpp; 23757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian const size_t length = bounds.width() * bpp; 23857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t h = bounds.height(); 23957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian src_stride *= bpp; 24057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian dst_stride *= bpp; 24157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian while (h--) { 24257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian memcpy(dst, src, length); 24357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian dst += dst_stride; 24457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian src += src_stride; 24557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 24657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 24757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 24857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buf->unlock(); 249076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 25057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buffer->unlock(); 25157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 25354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else 25454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif 25554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian { 256fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath: 25757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 2583330b203039dea366d4981db1408a460134b2d2cMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 25957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 260076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GGLSurface t; 2613330b203039dea366d4981db1408a460134b2d2cMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 2620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 2630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian res, strerror(res), buffer.get()); 2640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (res == NO_ERROR) { 2653330b203039dea366d4981db1408a460134b2d2cMathias Agopian loadTexture(&mTextures[0], dirty, t); 2660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian buffer->unlock(); 267076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2733330b203039dea366d4981db1408a460134b2d2cMathias Agopian int index = mFrontBufferIndex; 2743330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mTextures[index].image == EGL_NO_IMAGE_KHR) 2753330b203039dea366d4981db1408a460134b2d2cMathias Agopian index = 0; 276076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GLuint textureName = mTextures[index].name; 277076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (UNLIKELY(textureName == -1LU)) { 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in fact never been drawn into. this happens frequently with 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // SurfaceView. 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project clearWithOpenGL(clip); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2841fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian drawWithOpenGL(clip, mTextures[index]); 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2873330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage) 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2893330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 29148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 29248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 29348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian sp<Client> ourClient(client.promote()); 29448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (ourClient == 0) { 29548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 29648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 29748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 29848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 299076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 300cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 301cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 303076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * 304cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer cannot become the front buffer under our feet, since we're called 307cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * from Surface::dequeue() 308076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 309cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->assertReallocate(index); 310cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 31148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err != NO_ERROR) { 31248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the surface may have died 31348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 31448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 31548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 31648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian uint32_t w, h; 31748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 31848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 31948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian w = mWidth; 32048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian h = mHeight; 32148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian buffer = mBuffers[index]; 3226d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian 3236d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian // destroy() could have been called before we get here, we log it 3246d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian // because it's uncommon, and the code below should handle it 3256d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian LOGW_IF(buffer==0, 3266d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian "mBuffers[%d] is null (mWidth=%d, mHeight=%d)", 3276d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian index, w, h); 3286d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian 32948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mBuffers[index].clear(); 33048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 33148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 3336d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 3343330b203039dea366d4981db1408a460134b2d2cMathias Agopian err = buffer->reallocate(w, h, mFormat, effectiveUsage); 335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 336cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // here we have to reallocate a new buffer because we could have a 337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // client in our process with a reference to it (eg: status bar), 338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // and we can't release the handle under its feet. 339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer.clear(); 3403330b203039dea366d4981db1408a460134b2d2cMathias Agopian buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); 341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = buffer->initCheck(); 342076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 343cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 344cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 345cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 346cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 347cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 349cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 3507e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 3517e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 354cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 35548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 35648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (mWidth && mHeight) { 35748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // and we have new buffer 35848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mBuffers[index] = buffer; 35948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // texture is now dirty... 36048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mTextures[index].dirty = true; 36148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } else { 36248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops we got killed while we were allocating the buffer 36348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian buffer.clear(); 36448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 365f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 366cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 367f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 368f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 3693330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3703330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 3713330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 3723330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 3733330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3743330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3753330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 3763330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3773330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3783330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3793330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3813330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 3823330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3833330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 3843330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 3853330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3863330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3873330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3883330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 3893330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 390a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian if (mNoEGLImageForSwBuffers) { 391a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian if (usage & GraphicBuffer::USAGE_HW_MASK) { 392a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian // request EGLImage for h/w buffers only 393a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 394a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } 395a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } else { 396a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian // request EGLImage for all buffers 397a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 398a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } 3993330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 4003330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 4013330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 4023330b203039dea366d4981db1408a460134b2d2cMathias Agopian 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if ((front.requested_w != temp.requested_w) || 4097e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian (front.requested_h != temp.requested_h)) { 410cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "resize (layer=%p), requested (%dx%d), " 413cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "drawing (%d,%d), (%dx%d), (%dx%d)", 4147e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, 4157e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian int(temp.requested_w), int(temp.requested_h), 4167e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian int(front.requested_w), int(front.requested_h), 417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()), 418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight())); 419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 420cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we're being resized and there is a freeze display request, 421cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // acquire a freeze lock, so that the screen stays put 422cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // until we've redrawn at the new size; this is to avoid 423cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // glitches upon orientation changes. 424cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mFlinger->hasFreezeRequest()) { 425cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // if the surface is hidden, don't try to acquire the 426cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // freeze lock, since hidden surfaces may never redraw 427cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 428cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 431caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 432df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian // this will make sure LayerBase::doTransaction doesn't update 433df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian // the drawing state's size 434df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian Layer::State& editDraw(mDrawingState); 435df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian editDraw.requested_w = temp.requested_w; 436df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian editDraw.requested_h = temp.requested_h; 437df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 4386656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian // record the new size, form this point on, when the client request a 4396656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian // buffer, it'll get the new size. 4406656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian setDrawingSize(temp.requested_w, temp.requested_h); 4416656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 442caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian // all buffers need reallocation 443caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian lcblk->reallocate(); 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 457cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) { 458cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 459cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 460cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 469cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 470cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (buf < NO_ERROR) { 471cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian //LOGW("nothing to retire (%s)", strerror(-buf)); 472cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // NOTE: here the buffer is locked because we will used 473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // ouch, this really should never happen 478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (uint32_t(buf)>=NUM_BUFFERS) { 479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 484cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 485cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFrontBufferIndex = buf; 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 487cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // get the dirty region 4883330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 498df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 507d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 513d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 517d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 518d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 519d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 520d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 5218f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 522d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 523d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 524d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 525d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 526d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 527d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 528d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 529d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 530d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 531caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 532caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 533e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 534e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 535e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 536e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 538245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 539245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 540245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 541245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 542245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * for instance, a degenerate case could be that the user did an empty 543245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * update but repainted the buffer with appropriate content (after a 544245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian * resize for instance). 545245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian */ 546245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian reloadTexture( mPostedDirtyRegion ); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 568c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 569c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 5701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian // (because it may never be updated and therefore never release it) 571c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 572c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip() 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 577cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->unlock( mFrontBufferIndex ); 578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err!=NO_ERROR, 579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "layer %p, buffer=%d wasn't locked!", 580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, mFrontBufferIndex); 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 5851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 5861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 5871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 5891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append( lcblk->dump(" ") ); 5901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 5911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 5921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w0=0, h0=0, s0=0; 5931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian uint32_t w1=0, h1=0, s1=0; 5941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 5951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 5961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 5971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 5981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf1 != 0) { 6001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w1 = buf1->getWidth(); 6011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h1 = buf1->getHeight(); 6021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s1 = buf1->getStride(); 6031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 6041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 6051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 6061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 6071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 6081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian pixelFormat(), 6091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0, h0, s0, w1, h1, s1, 6101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian getFreezeLock().get(), stats.totalTime); 6111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 6121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 6131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 6141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 6179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 6189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian SurfaceID id, const sp<Layer>& owner) 6199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 6209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 6219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 6229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 6239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 6273330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 6293330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 631076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(uint32_t(index)>=NUM_BUFFERS, 633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "getBuffer() index (%d) out of range", index); 634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (uint32_t(index) < NUM_BUFFERS) { 635cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer = owner->requestBuffer(index, usage); 636cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 645