Layer.cpp revision 6f96080f333c70104424f42ac263c4c9c7a9dd2a
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h> 221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <cutils/native_handle.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Errors.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/StopWatch.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 286950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <ui/GraphicBuffer.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/PixelFormat.h> 30000479f9e325b4e426a67033abd92d47da412725Mathias Agopian 31000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include <surfaceflinger/Surface.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clz.h" 34781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian#include "GLExtensions.h" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Layer.h" 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SurfaceFlinger.h" 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_RESIZE 0 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45967dce306267109a6e8aec408b65609ac5642a03Mathias Agopiantemplate <typename T> inline T min(T a, T b) { 46967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian return a<b ? a : b; 47967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian} 48967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, 52593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian DisplayID display, const sp<Client>& client) 53593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian : LayerBaseClient(flinger, display, client), 54781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mGLExtensions(GLExtensions::getInstance()), 55cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsBlending(true), 569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mNeedsDithering(false), 577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mSecure(false), 58781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mTextureManager(), 592be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mBufferManager(mTextureManager), 60025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false), 61025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian mBypassState(false) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer() 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 67898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // FIXME: must be called from the main UI thread 68898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 69898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.destroy(dpy); 70898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // we can use getUserClientUnsafe here because we know we're 727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // single-threaded at that point. 737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (ourClient != 0) { 757623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ourClient->detachLayer(this); 767623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 789f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 796f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopianvoid Layer::destroy() const { 806f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian mFlinger->destroyLayer(this); 816f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian} 826f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian 837623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient, 847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedClient* sharedClient, int32_t token) 85593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian{ 865e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<SharedBufferServer> lcblk = new SharedBufferServer( 877623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sharedClient, token, mBufferManager.getDefaultBufferCount(), 887623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian getIdentity()); 89593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 907623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = mUserClientRef.setToken(userClient, lcblk, token); 915e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 925e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian LOGE_IF(err != NO_ERROR, 935e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian "ClientRef::setToken(%p, %p, %u) failed", 945e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian userClient.get(), lcblk.get(), token); 955e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 965e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (err == NO_ERROR) { 975e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian // we need to free the buffers associated with this surface 987623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 99593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1007623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return err; 1017623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 102593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1037623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::getToken() const 1047623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 1057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClientRef.getToken(); 106593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian} 107593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1085e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::getClient() const 1095e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 1105e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClientRef.getClient(); 1115e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 1125e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 1139f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 1149f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// in the purgatory list 1159f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianvoid Layer::onRemoved() 1169f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 1177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 1187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 1197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 120593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // wake up the condition 121593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->setStatus(NO_INIT); 122593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 123248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian} 1249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 1251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 127cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian return mSurface; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1306edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat format, uint32_t flags) 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 133cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // this surfaces pixel format 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 138cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // the display's pixel format 139cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 140967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian uint32_t const maxSurfaceDims = min( 141967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 142967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 143967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // never allow a surface larger than what our underlying GL implementation 144967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // can handle. 145967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 146967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian return BAD_VALUE; 147967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian } 148967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 149cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian PixelFormatInfo displayInfo; 150cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 151351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 152351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian 1539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 154967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian mWidth = w; 1559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 156c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 157c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqFormat = format; 158c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqWidth = w; 159c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqHeight = h; 160c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 1616950e428feaccc8164b989ef64e771a99948797aMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 163967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 164cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // we use the red index 165cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 166cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 167cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 168cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 169cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian mSurface = new SurfaceLayer(mFlinger, this); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 176083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian if (buffer == NULL) { 177083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // this situation can happen if we ran out of memory for instance. 178083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // not much we can do. continue to use whatever texture was bound 179083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // to this context. 180083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian return; 181083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian } 182083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian 183781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (mGLExtensions.haveDirectTexture()) { 1849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 1859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 1869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // not sure what we can do here... 1879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian goto slowpath; 1881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 189781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 1901d211f8ee0b422a3a741c3f88246c7c72ce483b0Mathias Agopianslowpath: 1911473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 192c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) { 193c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 194c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 195c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian res, strerror(res), buffer.get()); 196c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian if (res == NO_ERROR) { 197c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian mBufferManager.loadTexture(dirty, t); 198c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian buffer->unlock(); 199c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian } 200c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian } else { 201c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian // we can't do anything 2021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 206597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopianvoid Layer::drawForSreenShot() const 207597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian{ 2081989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const bool currentFiltering = mNeedsFiltering; 2091989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = true; 210597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian LayerBase::drawForSreenShot(); 2111989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering; 212597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian} 213597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2169f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Texture tex(mBufferManager.getActiveTexture()); 2179f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (tex.name == -1LU) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2192df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // in fact never been drawn into. This happens frequently with 2202df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // SurfaceView because the WindowManager can't know when the client 2212df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // has drawn the first time. 2222df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2232df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 2242df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // we just skip this update. 2252df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2262df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // figure out if there is something below us 2272df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region under; 2282df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 2292df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const size_t count = drawingLayers.size(); 2302df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian for (size_t i=0 ; i<count ; ++i) { 2312df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 2322df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 2332df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian break; 2342df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian under.orSelf(layer->visibleRegionScreen); 2352df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2362df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // if not everything below us is covered, we plug the holes! 2372df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region holes(clip.subtract(under)); 2382df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (!holes.isEmpty()) { 239f8b4b4408cb864bf604608221eafa9d37323d348Mathias Agopian clearWithOpenGL(holes, 0, 0, 0, 1); 2402df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 243025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 244025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS 245025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 246025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if ((buffer != NULL) && (buffer->transform)) { 247025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // Here we have a "bypass" buffer, but we need to composite it 248025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // most likely because it's not fullscreen anymore. 249025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // Since the buffer may have a transformation applied by the client 250025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // we need to inverse this transformation here. 251025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 252025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // calculate the inverse of the buffer transform 253025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const uint32_t mask = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H; 254025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const uint32_t bufferTransformInverse = buffer->transform ^ mask; 255025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 256025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // To accomplish the inverse transform, we use "mBufferTransform" 257025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // which is not used by Layer.cpp 258025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const_cast<Layer*>(this)->mBufferTransform = bufferTransformInverse; 259025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian drawWithOpenGL(clip, tex); 260025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // reset to "no transfrom" 261025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const_cast<Layer*>(this)->mBufferTransform = 0; 262025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return; 263025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 264025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif 265025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 2669f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian drawWithOpenGL(clip, tex); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopianbool Layer::needsFiltering() const 270923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian{ 271923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 2721989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian // if our buffer is not the same size than ourselves, 2731989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian // we need filtering. 2741989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian Mutex::Autolock _l(mLock); 2751989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian if (mNeedsScaling) 276923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return true; 277923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian } 278923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return LayerBase::needsFiltering(); 279923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian} 280923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian 28159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 28259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 28359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 2847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 2857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 2867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 28759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian // oops, the client is already gone 28859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return DEAD_OBJECT; 28959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 29059751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 291898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 292898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian status_t err = lcblk->resize(bufferCount); 293898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (err == NO_ERROR) 294898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.resize(bufferCount); 29559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 29659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 29759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 29859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 2992be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 3002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 3012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t usage) 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3036950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 304248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 3057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 3062be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 3072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 3082be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 3092be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 3102be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 311248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // this ensures our client doesn't go away while we're accessing 312248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the shared area. 3137623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 3147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 3157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 316248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops, the client is already gone 317248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 318248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 319248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 3201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 3219779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 3241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 325248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 326025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian uint32_t w, h, f, bypass; 327248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian { // scope for the lock 328248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 329c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 330025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian bypass = mBypassState; 331025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 332c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian // zero means default 3331989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mFixedSize = reqWidth && reqHeight; 334c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqFormat) reqFormat = mFormat; 335c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqWidth) reqWidth = mWidth; 336c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqHeight) reqHeight = mHeight; 337c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 338c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian w = reqWidth; 339c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian h = reqHeight; 340c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian f = reqFormat; 341c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 342c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) || 343c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian (reqFormat != mReqFormat)) { 344c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqWidth = reqWidth; 345c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqHeight = reqHeight; 346c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqFormat = reqFormat; 3471989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 348c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 3492be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian lcblk->reallocateAllExcept(index); 3502be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 351248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 352248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 35351c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // here we have to reallocate a new buffer because the buffer could be 35451c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // used as the front buffer, or by a client in our process 35551c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // (eg: status bar), and we can't release the handle under its feet. 356025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian uint32_t effectiveUsage = getEffectiveUsage(usage); 357025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 358025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian status_t err = NO_MEMORY; 359025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 360025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS 361025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (!mSecure && bypass && (effectiveUsage & GRALLOC_USAGE_HW_RENDER)) { 362025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // always allocate a buffer matching the screen size. the size 363025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // may be different from (w,h) if the buffer is rotated. 364025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 365025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t w = hw.getWidth(); 366025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t h = hw.getHeight(); 367025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t f = hw.getFormat(); 368025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 369025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage | GRALLOC_USAGE_HW_FB); 370025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian err = buffer->initCheck(); 371025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer->transform = uint8_t(getOrientation()); 372025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 373025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (err != NO_ERROR) { 374025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // allocation didn't succeed, probably because an older bypass 375025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // window hasn't released all its resources yet. 376025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 377025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 378025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (lcblk) { 379025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // all buffers need reallocation 380025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian lcblk->reallocateAll(); 381025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 382025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 383025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 384025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif 385025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 386025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (err != NO_ERROR) { 387025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 388025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian err = buffer->initCheck(); 389025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 3909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 392e869aee382cfe01d42dffba4912458a16bb791fbMathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 3939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3979779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 398e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 399e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, index, w, h, buffer->handle); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 403248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 4042be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mBufferManager.attachBuffer(index, buffer); 4056edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 4069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 4076edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 4086edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 4096950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 4106950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 4116950e428feaccc8164b989ef64e771a99948797aMathias Agopian /* 4126950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for software rendering, but h/w composition 4136950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 4146950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4156950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for h/w rendering and h/w composition 4166950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 4176950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4186950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 4196950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 4206950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4216950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 4226950e428feaccc8164b989ef64e771a99948797aMathias Agopian 4236950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mSecure) { 4246950e428feaccc8164b989ef64e771a99948797aMathias Agopian // secure buffer, don't store it into the GPU 4256950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 4266950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 4276950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 4286950e428feaccc8164b989ef64e771a99948797aMathias Agopian // it's allowed to modify the usage flags here, but generally 4296950e428feaccc8164b989ef64e771a99948797aMathias Agopian // the requested flags should be honored. 430aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian // request EGLImage for all buffers 431aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 4326950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 4336950e428feaccc8164b989ef64e771a99948797aMathias Agopian return usage; 4346950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 4356950e428feaccc8164b989ef64e771a99948797aMathias Agopian 436025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopianbool Layer::setBypass(bool enable) 437025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian{ 438025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian Mutex::Autolock _l(mLock); 439025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 440025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (mNeedsScaling || mNeedsFiltering) { 441025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return false; 442025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 443025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 444025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (mBypassState != enable) { 445025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian mBypassState = enable; 446025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 447025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 448025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (lcblk) { 449025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // all buffers need reallocation 450025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian lcblk->reallocateAll(); 451025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 452025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 453025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 454025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return true; 455025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian} 456025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 457ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopianvoid Layer::updateBuffersOrientation() 458ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian{ 459ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian sp<GraphicBuffer> buffer(getBypassBuffer()); 460ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian if (buffer != NULL && mOrientation != buffer->transform) { 461ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian ClientRef::Access sharedClient(mUserClientRef); 462ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 463ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian if (lcblk) { // all buffers need reallocation 464ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian lcblk->reallocateAll(); 465ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian } 466ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian } 467ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian} 468ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4742be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 4752be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian (front.requested_h != temp.requested_h); 4762be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 4772be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (sizeChanged) { 4789779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 4802be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 4812be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian this, 4822be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(temp.requested_w), int(temp.requested_h), 4832be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(front.requested_w), int(front.requested_h)); 4842be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 4852be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!isFixedSize()) { 4862be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // we're being resized and there is a freeze display request, 4872be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // acquire a freeze lock, so that the screen stays put 4882be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // until we've redrawn at the new size; this is to avoid 4892be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // glitches upon orientation changes. 4902be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (mFlinger->hasFreezeRequest()) { 4912be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // if the surface is hidden, don't try to acquire the 4922be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // freeze lock, since hidden surfaces may never redraw 4932be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 4942be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 4952be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4977cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 4982be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 4992be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // the drawing state's size 5002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Layer::State& editDraw(mDrawingState); 5012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_w = temp.requested_w; 5022be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_h = temp.requested_h; 503bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 5042be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size, form this point on, when the client request 5052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // a buffer, it'll get the new size. 5062be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 50770cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian 5087623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5097623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5107623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 511593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // all buffers need reallocation 512593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->reallocateAll(); 513593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 5142be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } else { 5152be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size 5162be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 5172be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5312be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 5329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 5339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 5349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 5351989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5382be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianbool Layer::isFixedSize() const { 5392be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Mutex::Autolock _l(mLock); 5402be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return mFixedSize; 5412be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian} 5422be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5497623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 552593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // client died 553593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian recomputeVisibleRegions = true; 554593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian return; 555593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 556593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 5579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 5589f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf == NOT_ENOUGH_DATA) { 5599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // NOTE: This is not an error, it simply means there is nothing to 5609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // retire. The buffer is locked because we will use it 5619779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5659f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf < NO_ERROR) { 5667623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 5679e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 5689e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian return; 5699e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 5709e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5719779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 5729f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 5737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 5749f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mPostedDirtyRegion.clear(); 5759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return; 5769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5786950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 5799e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer != NULL) { 580e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the dirty region 5819e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // compute the posted region 5829e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 5839e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 5849e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5859e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // update the layer size and release freeze-lock 5869e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Layer::State& front(drawingState()); 5879e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 5889e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian newFrontBuffer->getHeight() == front.requested_h) 589bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 5909e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if ((front.w != front.requested_w) || 5919e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian (front.h != front.requested_h)) 5929e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian { 5939e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // Here we pretend the transaction happened by updating the 5949e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // current and drawing states. Drawing state is only accessed 5959e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // in this thread, no need to have it locked 5969e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editDraw(mDrawingState); 5979e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.w = editDraw.requested_w; 5989e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.h = editDraw.requested_h; 5999e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 6009e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // We also need to update the current state so that we don't 6019e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // end-up doing too much work during the next transaction. 6029e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // NOTE: We actually don't need hold the transaction lock here 6039e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // because State::w and State::h are only accessed from 6049e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this thread 6059e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editTemp(currentState()); 6069e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.w = editDraw.w; 6079e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.h = editDraw.h; 6089e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 6099e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // recompute visible region 6109e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian recomputeVisibleRegions = true; 6119e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 61246b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian 6139e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // we now have the correct size, unfreeze the screen 6149e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mFreezeLock.clear(); 6159e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 616e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 617e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the crop region 618e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian setBufferCrop( lcblk->getCrop(buf) ); 619e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 620e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the transformation 621e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian setBufferTransform( lcblk->getTransform(buf) ); 622e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 6239e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } else { 6249e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this should not happen unless we ran out of memory while 6259e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // allocating the buffer. we're hoping that things will get back 6269e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // to normal the next time the app tries to draw into this buffer. 6279e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // meanwhile, pretend the screen didn't update. 6289e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 6297cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian } 6307cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 631e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian if (lcblk->getQueuedCount()) { 632e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian // signal an event if we have more buffers waiting 633e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian mFlinger->signalEvent(); 634e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 636a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 637a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 638a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 639a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 640a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * for instance, a degenerate case could be that the user did an empty 641a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * update but repainted the buffer with appropriate content (after a 642a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * resize for instance). 643a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian */ 644a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian reloadTexture( mPostedDirtyRegion ); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6665469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian if (visibleRegionScreen.isEmpty()) { 6675469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian // an invisible layer should not hold a freeze-lock 6689bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian // (because it may never be updated and therefore never release it) 6695469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian mFreezeLock.clear(); 6705469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian } 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739bce8737f2f7581ade57445286aa150de051ff89Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 6749bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian{ 6759bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 6769bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 6777623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 6787623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 6797623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian uint32_t totalTime = 0; 6807623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 6817623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 6827623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian totalTime= stats.totalTime; 6837623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result.append( lcblk->dump(" ") ); 6847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 6857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6869bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 6879bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 6889bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w0=0, h0=0, s0=0; 6899bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w1=0, h1=0, s1=0; 6909bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf0 != 0) { 6919bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w0 = buf0->getWidth(); 6929bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h0 = buf0->getHeight(); 6939bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s0 = buf0->getStride(); 6949bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 6959bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf1 != 0) { 6969bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w1 = buf1->getWidth(); 6979bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h1 = buf1->getHeight(); 6989bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s1 = buf1->getStride(); 6999bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 7009bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian snprintf(buffer, SIZE, 7019bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian " " 7029bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 703025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian " freezeLock=%p, bypass=%d, dq-q-time=%u us\n", 7047623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mFormat, w0, h0, s0, w1, h1, s1, 705025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian getFreezeLock().get(), mBypassState, totalTime); 7069bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 7079bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian result.append(buffer); 7089bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian} 7099bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 7101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 7111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 7127623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::ClientRef() 7135e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0), mToken(-1) { 7147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7167623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::~ClientRef() { 7177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::ClientRef::getToken() const { 7207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 7217623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mToken; 7227623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7237623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7245e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const { 7255e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian Mutex::Autolock _l(mLock); 7265e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClient.promote(); 7275e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 7285e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7297623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 7305e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian const sp<SharedBufferServer>& sharedClient, int32_t token) { 7317623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 7325e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7335e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian { // scope for strong mUserClient reference 7345e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<UserClient> userClient(mUserClient.promote()); 7355e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (mUserClient != 0 && mControlBlock != 0) { 7365e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock->setStatus(NO_INIT); 7375e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 7385e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 7395e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7407623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClient = uc; 7417623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mToken = token; 7425e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = sharedClient; 7437623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return NO_ERROR; 7447623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7457623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7467623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 7477623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClient.promote(); 7487623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7497623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// this class gives us access to SharedBufferServer safely 7517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// it makes sure the UserClient (and its associated shared memory) 7527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// won't go away while we're accessing it. 7537623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref) 7545e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0) 7557623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 7567623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(ref.mLock); 7577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClientStrongRef = ref.mUserClient.promote(); 7587623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mUserClientStrongRef != 0) 7595e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = ref.mControlBlock; 7605e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 7615e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7625e14010b1fc066dfcbc0a577d59492687c99667dMathias AgopianLayer::ClientRef::Access::~Access() 7635e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 7647623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7657623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7667623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// --------------------------------------------------------------------------- 7677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7689f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 769898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 7707623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mActiveBuffer(-1), mFailover(false) 771898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 772898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 773898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 774898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias AgopianLayer::BufferManager::~BufferManager() 7759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 7769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 778898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size) 779898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 780898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 781898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mNumBuffers = size; 782898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 7839f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// only for debugging 7869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 7879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mBufferData[index].buffer; 7889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 7919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mActiveBuffer = index; 7929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 7939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7959f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 7969f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mActiveBuffer; 7979f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7989f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7999f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 800898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Texture res; 8017623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mFailover || mActiveBuffer<0) { 802898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian res = mFailoverTexture; 803898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } else { 804898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 805898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 806898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return res; 8079f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8099f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 8107623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<GraphicBuffer> result; 8117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian const ssize_t activeBuffer = mActiveBuffer; 8127623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (activeBuffer >= 0) { 8137623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian BufferData const * const buffers = mBufferData; 8147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 8157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result = buffers[activeBuffer].buffer; 8167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 8177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return result; 8189f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8199f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8209f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 8219f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 822898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 8239f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer; 8249f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 825898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffer = buffers[index].buffer; 826898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = 0; 8279f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return buffer; 8289f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8299f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8309f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 8319f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 8329f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 833898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 8349f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 835898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = buffer; 836898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].texture.dirty = true; 8379f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 8389f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8399f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8409f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 8419f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 842898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 843898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian size_t num; 844898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian { // scope for the lock 845898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 846898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian num = mNumBuffers; 847898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 848898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[i].buffer = 0; 849898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 850898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 851898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 852898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 8539f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8549f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian destroyTexture(&mFailoverTexture, dpy); 8559f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 8569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8579f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8589f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 8599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 8609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 8617623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = NO_INIT; 8627623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ssize_t index = mActiveBuffer; 8637623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (index >= 0) { 864781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (!mFailover) { 865781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian Image& texture(mBufferData[index].texture); 866781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = mTextureManager.initEglImage(&texture, dpy, buffer); 867781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 868781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // free all resources associated with using EGLImages. 869781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (err == NO_ERROR) { 870781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = false; 871781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mFailoverTexture, dpy); 872781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 873781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = true; 874781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian const size_t num = mNumBuffers; 875781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian for (size_t i=0 ; i<num ; i++) { 876781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 877781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } 878330dd304a471d260a73e342a240921c03c825f99Andreas Huber } 879781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 880781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // we failed once, don't try again 881781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = BAD_VALUE; 8829f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8839f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return err; 8859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::loadTexture( 8889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const Region& dirty, const GGLSurface& t) 8899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 8909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 8919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 893898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 894898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 895898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->name != -1U) { 896898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian glDeleteTextures(1, &tex->name); 897898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->name = -1U; 898898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 899898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 900898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 901898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 902898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 903898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 904898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 905898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 9069f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// --------------------------------------------------------------------------- 9079f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 9086cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 909593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian const sp<Layer>& owner) 910593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 9116cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 9126cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 9136cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 9146cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 9151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 9161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 9171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 9182be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 9192be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 9201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 9216950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 9221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 9231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 924898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 925898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * requestBuffer() cannot be called from the main thread 926898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 927898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 928898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 9292be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 9301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 9311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 9321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 93559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 93659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian status_t err = DEAD_OBJECT; 93759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian sp<Layer> owner(getOwner()); 93859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian if (owner != 0) { 939898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 940898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * setBufferCount() cannot be called from the main thread 941898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 942898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 943898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 94459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian err = owner->setBufferCount(bufferCount); 94559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 94659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 94759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 94859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 953