Layer.cpp revision d343e3d5e3177806205b9452b0b43907e28afd9a
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 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4; 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const Layer::typeID = "Layer"; 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display, 52cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian const sp<Client>& c, int32_t i) 5348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian : LayerBaseClient(flinger, display, c, i), 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecure(false), 55a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian mNoEGLImageForSwBuffers(false), 56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsBlending(true), 57401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering(false) 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // no OpenGL operation is possible here, since we might not be 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the OpenGL thread. 61cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFrontBufferIndex = lcblk->getFrontBuffer(); 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian destroy(); 670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the actual buffers will be destroyed here 6848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 69cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopianvoid Layer::destroy() 710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian{ 72cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mTextures[i].name != -1U) { 74550b79f4491909b0f223d8fb25155974f53b3f79Mathias Agopian glDeleteTextures(1, &mTextures[i].name); 750aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian mTextures[i].name = -1U; 76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mTextures[i].image != EGL_NO_IMAGE_KHR) { 78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian eglDestroyImageKHR(dpy, mTextures[i].image); 800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 8248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 83cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mBuffers[i].clear(); 8448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mWidth = mHeight = 0; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian mSurface.clear(); 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSurface; 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch() 959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // the layer is not on screen anymore. free as much resources as possible 97f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian mFreezeLock.clear(); 988c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian destroy(); 999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return NO_ERROR; 1009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 1019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 102f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 105401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 110401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 111401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 112401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian PixelFormatInfo displayInfo; 113401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 114a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 115a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 116cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 117cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 118cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 1193330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 121a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS); 122a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian 123401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // we use the red index 124401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 125401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 126401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 127401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 128cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 1293330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBuffers[i] = new GraphicBuffer(); 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 137cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 1389ec430adaea1cb88eaa1e78c7f759cd42ab6cf7aMathias Agopian sp<GraphicBuffer> buffer(getFrontBufferLocked()); 1398f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian if (buffer == NULL) { 1408f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // this situation can happen if we ran out of memory for instance. 1418f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // not much we can do. continue to use whatever texture was bound 1428f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // to this context. 1438f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian return; 1448f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian } 1458f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 1468f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian const int index = mFrontBufferIndex; 14757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 14857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian // create the new texture name if needed 14957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (UNLIKELY(mTextures[index].name == -1U)) { 15057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].name = createTexture(); 15157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].width = 0; 15257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mTextures[index].height = 0; 15357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 15457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 15554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer 15657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mFlags & DisplayHardware::DIRECT_TEXTURE) { 15757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) { 15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mTextures[index].dirty) { 159fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) { 160fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian // not sure what we can do here... 161fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 162fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian goto slowpath; 163fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian } 16457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 165076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else { 16657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width || 16757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer->height != buffer->height)) { 16857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer.clear(); 16957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian mHybridBuffer = new GraphicBuffer( 17057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buffer->width, buffer->height, buffer->format, 17157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN | 17257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GraphicBuffer::USAGE_HW_TEXTURE); 173fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian if (initializeEglImage( 174fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mHybridBuffer, &mTextures[0]) != NO_ERROR) { 175fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian // not sure what we can do here... 176fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 177fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian mHybridBuffer.clear(); 178fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian goto slowpath; 179fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian } 180076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 18257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GGLSurface t; 18357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 18457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 18557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian res, strerror(res), buffer.get()); 18657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (res == NO_ERROR) { 18757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian Texture* const texture(&mTextures[0]); 18857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 18957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian glBindTexture(GL_TEXTURE_2D, texture->name); 19057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 19157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian sp<GraphicBuffer> buf(mHybridBuffer); 19257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian void* vaddr; 19357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr); 19457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (res == NO_ERROR) { 19557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian int bpp = 0; 19657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian switch (t.format) { 19754ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGB_565: 19854ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBA_4444: 19957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bpp = 2; 20057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian break; 20154ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 20254ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_RGBX_8888: 20357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bpp = 4; 20457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian break; 20557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian default: 20654ed4f6282bdea251455f39b978626026affdbefMathias Agopian if (isSupportedYuvFormat(t.format)) { 20754ed4f6282bdea251455f39b978626026affdbefMathias Agopian // just show the Y plane of YUV buffers 20854ed4f6282bdea251455f39b978626026affdbefMathias Agopian bpp = 1; 20954ed4f6282bdea251455f39b978626026affdbefMathias Agopian break; 21054ed4f6282bdea251455f39b978626026affdbefMathias Agopian } 21157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian // oops, we don't handle this format! 21257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian LOGE("layer %p, texture=%d, using format %d, which is not " 21357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian "supported by the GL", this, texture->name, t.format); 21457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 21557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (bpp) { 21657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian const Rect bounds(dirty.getBounds()); 21757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t src_stride = t.stride; 21857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t dst_stride = buf->stride; 21957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian if (src_stride == dst_stride && 22057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bounds.width() == t.width && 22157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian bounds.height() == t.height) 22257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian { 22357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian memcpy(vaddr, t.data, t.height * t.stride * bpp); 22457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } else { 22557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GLubyte const * src = t.data + 22657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian (bounds.left + bounds.top * src_stride) * bpp; 22757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian GLubyte * dst = (GLubyte *)vaddr + 22857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian (bounds.left + bounds.top * dst_stride) * bpp; 22957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian const size_t length = bounds.width() * bpp; 23057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian size_t h = bounds.height(); 23157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian src_stride *= bpp; 23257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian dst_stride *= bpp; 23357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian while (h--) { 23457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian memcpy(dst, src, length); 23557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian dst += dst_stride; 23657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian src += src_stride; 23757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 23857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 23957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 24057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buf->unlock(); 241076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 24257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian buffer->unlock(); 24357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 244076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 24554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else 24654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif 24754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian { 248fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath: 24957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 2503330b203039dea366d4981db1408a460134b2d2cMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 25157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian } 252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GGLSurface t; 2533330b203039dea366d4981db1408a460134b2d2cMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 2540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 2550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian res, strerror(res), buffer.get()); 2560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (res == NO_ERROR) { 2573330b203039dea366d4981db1408a460134b2d2cMathias Agopian loadTexture(&mTextures[0], dirty, t); 2580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian buffer->unlock(); 259076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2653330b203039dea366d4981db1408a460134b2d2cMathias Agopian int index = mFrontBufferIndex; 2663330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mTextures[index].image == EGL_NO_IMAGE_KHR) 2673330b203039dea366d4981db1408a460134b2d2cMathias Agopian index = 0; 268076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GLuint textureName = mTextures[index].name; 269076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (UNLIKELY(textureName == -1LU)) { 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in fact never been drawn into. this happens frequently with 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // SurfaceView. 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project clearWithOpenGL(clip); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2761fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian drawWithOpenGL(clip, mTextures[index]); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2793330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage) 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2813330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 28248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 28348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // this ensures our client doesn't go away while we're accessing 28448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the shared area. 28548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian sp<Client> ourClient(client.promote()); 28648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (ourClient == 0) { 28748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops, the client is already gone 28848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 28948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian /* 292cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * This is called from the client's Surface::dequeue(). This can happen 293cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * at any time, especially while we're in the middle of using the 294cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer 'index' as our front buffer. 295076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * 296cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 297cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 298cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * buffer cannot become the front buffer under our feet, since we're called 299cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian * from Surface::dequeue() 300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 301cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->assertReallocate(index); 302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 30348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err != NO_ERROR) { 30448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // the surface may have died 30548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return buffer; 30648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 30748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 30848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian uint32_t w, h; 30948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian { // scope for the lock 31048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 31148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian w = mWidth; 31248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian h = mHeight; 31348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian buffer = mBuffers[index]; 3146d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian 3156d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian // destroy() could have been called before we get here, we log it 3166d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian // because it's uncommon, and the code below should handle it 3176d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian LOGW_IF(buffer==0, 3186d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian "mBuffers[%d] is null (mWidth=%d, mHeight=%d)", 3196d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian index, w, h); 3206d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian 32148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mBuffers[index].clear(); 32248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 32348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 3243330b203039dea366d4981db1408a460134b2d2cMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 3256d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 3263330b203039dea366d4981db1408a460134b2d2cMathias Agopian err = buffer->reallocate(w, h, mFormat, effectiveUsage); 327cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // here we have to reallocate a new buffer because we could have a 329cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // client in our process with a reference to it (eg: status bar), 330cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // and we can't release the handle under its feet. 331cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer.clear(); 3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); 333cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = buffer->initCheck(); 334076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 336cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err || buffer->handle == 0) { 337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err || buffer->handle == 0, 338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, index, w, h, strerror(-err)); 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGD_IF(DEBUG_RESIZE, 3427e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 3437e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, index, w, h, buffer->handle); 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 346cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 34748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian Mutex::Autolock _l(mLock); 34848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (mWidth && mHeight) { 34948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // and we have new buffer 35048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mBuffers[index] = buffer; 35148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // texture is now dirty... 35248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mTextures[index].dirty = true; 35348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } else { 35448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian // oops we got killed while we were allocating the buffer 35548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian buffer.clear(); 35648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 357f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 358cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return buffer; 359f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian} 360f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian 3613330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3623330b203039dea366d4981db1408a460134b2d2cMathias Agopian{ 3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian /* 3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for software rendering, but h/w composition 3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3663330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3673330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used for h/w rendering and h/w composition 3683330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3693330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3703330b203039dea366d4981db1408a460134b2d2cMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3713330b203039dea366d4981db1408a460134b2d2cMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3723330b203039dea366d4981db1408a460134b2d2cMathias Agopian * 3733330b203039dea366d4981db1408a460134b2d2cMathias Agopian */ 3743330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3753330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (mSecure) { 3763330b203039dea366d4981db1408a460134b2d2cMathias Agopian // secure buffer, don't store it into the GPU 3773330b203039dea366d4981db1408a460134b2d2cMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3783330b203039dea366d4981db1408a460134b2d2cMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3793330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian // it's allowed to modify the usage flags here, but generally 3813330b203039dea366d4981db1408a460134b2d2cMathias Agopian // the requested flags should be honored. 382a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian if (mNoEGLImageForSwBuffers) { 383a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian if (usage & GraphicBuffer::USAGE_HW_MASK) { 384a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian // request EGLImage for h/w buffers only 385a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 386a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } 387a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } else { 388a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian // request EGLImage for all buffers 389a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 390a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian } 3913330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3923330b203039dea366d4981db1408a460134b2d2cMathias Agopian return usage; 3933330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 3943330b203039dea366d4981db1408a460134b2d2cMathias Agopian 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4007e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if ((front.requested_w != temp.requested_w) || 4017e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian (front.requested_h != temp.requested_h)) { 402cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 404cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "resize (layer=%p), requested (%dx%d), " 405cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "drawing (%d,%d), (%dx%d), (%dx%d)", 4067e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian this, 4077e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian int(temp.requested_w), int(temp.requested_h), 4087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian int(front.requested_w), int(front.requested_h), 409cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()), 410cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight())); 411cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we're being resized and there is a freeze display request, 413cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // acquire a freeze lock, so that the screen stays put 414cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // until we've redrawn at the new size; this is to avoid 415cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // glitches upon orientation changes. 416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mFlinger->hasFreezeRequest()) { 417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // if the surface is hidden, don't try to acquire the 418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // freeze lock, since hidden surfaces may never redraw 419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 420cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 423caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 424df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian // this will make sure LayerBase::doTransaction doesn't update 425df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian // the drawing state's size 426df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian Layer::State& editDraw(mDrawingState); 427df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian editDraw.requested_w = temp.requested_w; 428df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian editDraw.requested_h = temp.requested_h; 429df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian 4306656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian // record the new size, form this point on, when the client request a 4316656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian // buffer, it'll get the new size. 4326656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian setDrawingSize(temp.requested_w, temp.requested_h); 4336656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 434caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian // all buffers need reallocation 435caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian lcblk->reallocate(); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 437cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 449cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) { 450cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mLock); 451cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mWidth = w; 452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mHeight = h; 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 461cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t buf = lcblk->retireAndLock(); 462cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (buf < NO_ERROR) { 463cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian //LOGW("nothing to retire (%s)", strerror(-buf)); 464cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // NOTE: here the buffer is locked because we will used 465cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // for composition later in the loop 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 468d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 469d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // ouch, this really should never happen 470d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (uint32_t(buf)>=NUM_BUFFERS) { 471d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", buf); 472d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 473d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return; 474d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 476cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // we retired a buffer, which becomes the new front buffer 477cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFrontBufferIndex = buf; 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 479cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // get the dirty region 4803330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer != NULL) { 482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // compute the posted region 483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 484d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 485d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // update the layer size and release freeze-lock 487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian const Layer::State& front(drawingState()); 488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 490df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian { 491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if ((front.w != front.requested_w) || 492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian (front.h != front.requested_h)) 493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian { 494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Here we pretend the transaction happened by updating the 495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // current and drawing states. Drawing state is only accessed 496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // in this thread, no need to have it locked 497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editDraw(mDrawingState); 498d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.w = editDraw.requested_w; 499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editDraw.h = editDraw.requested_h; 500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // We also need to update the current state so that we don't 502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // end-up doing too much work during the next transaction. 503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // because State::w and State::h are only accessed from 505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this thread 506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Layer::State& editTemp(currentState()); 507d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.w = editDraw.w; 508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian editTemp.h = editDraw.h; 509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // recompute visible region 511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian recomputeVisibleRegions = true; 512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 5138f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian 514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // we now have the correct size, unfreeze the screen 515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mFreezeLock.clear(); 516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 517d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 518d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // this should not happen unless we ran out of memory while 519d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // allocating the buffer. we're hoping that things will get back 520d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // to normal the next time the app tries to draw into this buffer. 521d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // meanwhile, pretend the screen didn't update. 522d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPostedDirtyRegion.clear(); 523caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian } 524caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian 525e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian if (lcblk->getQueuedCount()) { 526e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian // signal an event if we have more buffers waiting 527e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian mFlinger->signalEvent(); 528e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5303330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (!mPostedDirtyRegion.isEmpty()) { 5313330b203039dea366d4981db1408a460134b2d2cMathias Agopian reloadTexture( mPostedDirtyRegion ); 5323330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 554c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian if (visibleRegionScreen.isEmpty()) { 555c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // an invisible layer should not hold a freeze-lock 556c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian // (because it may never be updated and thereore never release it) 557c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian mFreezeLock.clear(); 558c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip() 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 563cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = lcblk->unlock( mFrontBufferIndex ); 564cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err!=NO_ERROR, 565cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "layer %p, buffer=%d wasn't locked!", 566cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian this, mFrontBufferIndex); 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 5729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian SurfaceID id, const sp<Layer>& owner) 5739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 5749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 5759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 5769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 5779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5813330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 5833330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer; 584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Layer> owner(getOwner()); 585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (owner != 0) { 586cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(uint32_t(index)>=NUM_BUFFERS, 587cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "getBuffer() index (%d) out of range", index); 588cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (uint32_t(index) < NUM_BUFFERS) { 589cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian buffer = owner->requestBuffer(index, usage); 590cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return buffer; 593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 599