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{ 63afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopian setDestroyer(this); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer() 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 68898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // FIXME: must be called from the main UI thread 69898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 70898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.destroy(dpy); 71898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // we can use getUserClientUnsafe here because we know we're 737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // single-threaded at that point. 747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 757623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (ourClient != 0) { 767623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ourClient->detachLayer(this); 777623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 789f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 799f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 80afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopianvoid Layer::destroy(RefBase const* base) { 81afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopian mFlinger->destroyLayer(static_cast<LayerBase const*>(base)); 826f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian} 836f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian 847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient, 857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedClient* sharedClient, int32_t token) 86593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian{ 875e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<SharedBufferServer> lcblk = new SharedBufferServer( 887623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sharedClient, token, mBufferManager.getDefaultBufferCount(), 897623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian getIdentity()); 90593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 917623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = mUserClientRef.setToken(userClient, lcblk, token); 925e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 935e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian LOGE_IF(err != NO_ERROR, 945e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian "ClientRef::setToken(%p, %p, %u) failed", 955e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian userClient.get(), lcblk.get(), token); 965e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 975e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (err == NO_ERROR) { 985e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian // we need to free the buffers associated with this surface 997623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 100593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1017623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return err; 1027623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 103593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1047623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::getToken() const 1057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 1067623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClientRef.getToken(); 107593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian} 108593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1095e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::getClient() const 1105e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 1115e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClientRef.getClient(); 1125e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 1135e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 1149f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 1159f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// in the purgatory list 1169f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianvoid Layer::onRemoved() 1179f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 1187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 1197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 1207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 121593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // wake up the condition 122593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->setStatus(NO_INIT); 123593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 124248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian} 1259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 1261473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 128cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian return mSurface; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1316edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat format, uint32_t flags) 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 134cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // this surfaces pixel format 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 139cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // the display's pixel format 140cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 141967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian uint32_t const maxSurfaceDims = min( 142967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 143967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 144967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // never allow a surface larger than what our underlying GL implementation 145967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // can handle. 146967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 147967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian return BAD_VALUE; 148967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian } 149967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 150cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian PixelFormatInfo displayInfo; 151cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 152351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 153351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian 1549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 155967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian mWidth = w; 1569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 157c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 158c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqFormat = format; 159c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqWidth = w; 160c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqHeight = h; 161c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 1626950e428feaccc8164b989ef64e771a99948797aMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 164967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 165cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // we use the red index 166cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 167cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 168cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 169cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 170cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian mSurface = new SurfaceLayer(mFlinger, this); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 177083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian if (buffer == NULL) { 178083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // this situation can happen if we ran out of memory for instance. 179083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // not much we can do. continue to use whatever texture was bound 180083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // to this context. 181083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian return; 182083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian } 183083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian 184781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (mGLExtensions.haveDirectTexture()) { 1859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 1869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 1879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // not sure what we can do here... 1889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian goto slowpath; 1891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 190781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 1911d211f8ee0b422a3a741c3f88246c7c72ce483b0Mathias Agopianslowpath: 1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 193c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) { 194c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 195c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 196c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian res, strerror(res), buffer.get()); 197c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian if (res == NO_ERROR) { 198c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian mBufferManager.loadTexture(dirty, t); 199c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian buffer->unlock(); 200c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian } 201c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian } else { 202c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian // we can't do anything 2031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 207597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopianvoid Layer::drawForSreenShot() const 208597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian{ 2091989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const bool currentFiltering = mNeedsFiltering; 2101989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = true; 211597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian LayerBase::drawForSreenShot(); 2121989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering; 213597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian} 214597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2179f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Texture tex(mBufferManager.getActiveTexture()); 2189f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (tex.name == -1LU) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2202df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // in fact never been drawn into. This happens frequently with 2212df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // SurfaceView because the WindowManager can't know when the client 2222df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // has drawn the first time. 2232df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2242df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 2252df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // we just skip this update. 2262df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2272df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // figure out if there is something below us 2282df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region under; 2292df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 2302df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const size_t count = drawingLayers.size(); 2312df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian for (size_t i=0 ; i<count ; ++i) { 2322df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 2332df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 2342df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian break; 2352df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian under.orSelf(layer->visibleRegionScreen); 2362df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2372df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // if not everything below us is covered, we plug the holes! 2382df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region holes(clip.subtract(under)); 2392df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (!holes.isEmpty()) { 240f8b4b4408cb864bf604608221eafa9d37323d348Mathias Agopian clearWithOpenGL(holes, 0, 0, 0, 1); 2412df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 244025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 245025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS 246025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 247025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if ((buffer != NULL) && (buffer->transform)) { 248025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // Here we have a "bypass" buffer, but we need to composite it 249025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // most likely because it's not fullscreen anymore. 250025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // Since the buffer may have a transformation applied by the client 251025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // we need to inverse this transformation here. 252025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 253025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // calculate the inverse of the buffer transform 254025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const uint32_t mask = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H; 255025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const uint32_t bufferTransformInverse = buffer->transform ^ mask; 256025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 257025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // To accomplish the inverse transform, we use "mBufferTransform" 258025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // which is not used by Layer.cpp 259025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const_cast<Layer*>(this)->mBufferTransform = bufferTransformInverse; 260025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian drawWithOpenGL(clip, tex); 261025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // reset to "no transfrom" 262025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const_cast<Layer*>(this)->mBufferTransform = 0; 263025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return; 264025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 265025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif 266025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 2679f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian drawWithOpenGL(clip, tex); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 270923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopianbool Layer::needsFiltering() const 271923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian{ 272923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 2731989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian // if our buffer is not the same size than ourselves, 2741989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian // we need filtering. 2751989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian Mutex::Autolock _l(mLock); 2761989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian if (mNeedsScaling) 277923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return true; 278923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian } 279923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return LayerBase::needsFiltering(); 280923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian} 281923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian 28259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 28359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 28459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 2857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 2867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 2877623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 28859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian // oops, the client is already gone 28959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return DEAD_OBJECT; 29059751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 29159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 292898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 293898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian status_t err = lcblk->resize(bufferCount); 294898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (err == NO_ERROR) 295898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.resize(bufferCount); 29659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 29759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 29859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 29959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 3002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 3012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 3022be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t usage) 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3046950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 305248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 3067623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 3072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 3082be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 3092be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 3102be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 3112be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 312248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // this ensures our client doesn't go away while we're accessing 313248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the shared area. 3147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 3157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 3167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 317248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops, the client is already gone 318248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 319248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 320248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 3211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 3249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 3251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 326248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 327025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian uint32_t w, h, f, bypass; 328248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian { // scope for the lock 329248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 330c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 331025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian bypass = mBypassState; 332025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 333c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian // zero means default 3341989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mFixedSize = reqWidth && reqHeight; 335c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqFormat) reqFormat = mFormat; 336c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqWidth) reqWidth = mWidth; 337c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if (!reqHeight) reqHeight = mHeight; 338c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 339c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian w = reqWidth; 340c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian h = reqHeight; 341c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian f = reqFormat; 342c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 343c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) || 344c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian (reqFormat != mReqFormat)) { 345c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqWidth = reqWidth; 346c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqHeight = reqHeight; 347c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian mReqFormat = reqFormat; 3481989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 349c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian 3502be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian lcblk->reallocateAllExcept(index); 3512be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 352248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 353248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 35451c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // here we have to reallocate a new buffer because the buffer could be 35551c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // used as the front buffer, or by a client in our process 35651c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // (eg: status bar), and we can't release the handle under its feet. 357025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian uint32_t effectiveUsage = getEffectiveUsage(usage); 358025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 359025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian status_t err = NO_MEMORY; 360025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 361025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS 362025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (!mSecure && bypass && (effectiveUsage & GRALLOC_USAGE_HW_RENDER)) { 363025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // always allocate a buffer matching the screen size. the size 364025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // may be different from (w,h) if the buffer is rotated. 365025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 366025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t w = hw.getWidth(); 367025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t h = hw.getHeight(); 368025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian int32_t f = hw.getFormat(); 369025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 370025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage | GRALLOC_USAGE_HW_FB); 371025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian err = buffer->initCheck(); 372025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer->transform = uint8_t(getOrientation()); 373025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 374025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (err != NO_ERROR) { 375025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // allocation didn't succeed, probably because an older bypass 376025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // window hasn't released all its resources yet. 377025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 378025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 379025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (lcblk) { 380025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // all buffers need reallocation 381025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian lcblk->reallocateAll(); 382025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 383025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 384025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 385025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif 386025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 387025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (err != NO_ERROR) { 388025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 389025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian err = buffer->initCheck(); 390025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 3919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3929779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 393e869aee382cfe01d42dffba4912458a16bb791fbMathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 3969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 399e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 400e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, index, w, h, buffer->handle); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 404248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 4052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mBufferManager.attachBuffer(index, buffer); 4066edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 4079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 4086edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 4096edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 4106950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 4116950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 4126950e428feaccc8164b989ef64e771a99948797aMathias Agopian /* 4136950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for software rendering, but h/w composition 4146950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 4156950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4166950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for h/w rendering and h/w composition 4176950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 4186950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4196950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 4206950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 4216950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 4226950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 4236950e428feaccc8164b989ef64e771a99948797aMathias Agopian 4246950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mSecure) { 4256950e428feaccc8164b989ef64e771a99948797aMathias Agopian // secure buffer, don't store it into the GPU 4266950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 4276950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 4286950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 4296950e428feaccc8164b989ef64e771a99948797aMathias Agopian // it's allowed to modify the usage flags here, but generally 4306950e428feaccc8164b989ef64e771a99948797aMathias Agopian // the requested flags should be honored. 431aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian // request EGLImage for all buffers 432aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 4336950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 4346950e428feaccc8164b989ef64e771a99948797aMathias Agopian return usage; 4356950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 4366950e428feaccc8164b989ef64e771a99948797aMathias Agopian 437025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopianbool Layer::setBypass(bool enable) 438025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian{ 439025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian Mutex::Autolock _l(mLock); 440025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 441025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (mNeedsScaling || mNeedsFiltering) { 442025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return false; 443025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 444025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 445025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (mBypassState != enable) { 446025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian mBypassState = enable; 447025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 448025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 449025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian if (lcblk) { 450025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian // all buffers need reallocation 451025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian lcblk->reallocateAll(); 452025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 453025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian } 454025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 455025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian return true; 456025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian} 457025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian 458ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopianvoid Layer::updateBuffersOrientation() 459ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian{ 460ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian sp<GraphicBuffer> buffer(getBypassBuffer()); 461ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian if (buffer != NULL && mOrientation != buffer->transform) { 462ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian ClientRef::Access sharedClient(mUserClientRef); 463ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 464ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian if (lcblk) { // all buffers need reallocation 465ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian lcblk->reallocateAll(); 466ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian } 467ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian } 468ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian} 469ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4752be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 4762be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian (front.requested_h != temp.requested_h); 4772be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 4782be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (sizeChanged) { 4799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 4812be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 4822be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian this, 4832be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(temp.requested_w), int(temp.requested_h), 4842be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(front.requested_w), int(front.requested_h)); 4852be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 4862be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!isFixedSize()) { 4872be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // we're being resized and there is a freeze display request, 4882be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // acquire a freeze lock, so that the screen stays put 4892be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // until we've redrawn at the new size; this is to avoid 4902be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // glitches upon orientation changes. 4912be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (mFlinger->hasFreezeRequest()) { 4922be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // if the surface is hidden, don't try to acquire the 4932be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // freeze lock, since hidden surfaces may never redraw 4942be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 4952be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 4962be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4987cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 4992be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 5002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // the drawing state's size 5012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Layer::State& editDraw(mDrawingState); 5022be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_w = temp.requested_w; 5032be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_h = temp.requested_h; 504bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 5052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size, form this point on, when the client request 5062be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // a buffer, it'll get the new size. 5072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 50870cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian 5097623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5107623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 512593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // all buffers need reallocation 513593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->reallocateAll(); 514593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 5152be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } else { 5162be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size 5172be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 5182be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5322be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 5339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 5349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 5359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 5361989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5392be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianbool Layer::isFixedSize() const { 5402be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Mutex::Autolock _l(mLock); 5412be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return mFixedSize; 5422be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian} 5432be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 553593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // client died 554593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian recomputeVisibleRegions = true; 555593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian return; 556593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 557593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 5589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 5599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf == NOT_ENOUGH_DATA) { 5609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // NOTE: This is not an error, it simply means there is nothing to 5619f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // retire. The buffer is locked because we will use it 5629779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5669f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf < NO_ERROR) { 5677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 5689e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 5699e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian return; 5709e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 5719e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5729779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 5739f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 5747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 5759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mPostedDirtyRegion.clear(); 5769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return; 5779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5796950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 5809e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer != NULL) { 581e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the dirty region 5829e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // compute the posted region 5839e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 5849e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 5859e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5869e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // update the layer size and release freeze-lock 5879e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Layer::State& front(drawingState()); 5889e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 5899e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian newFrontBuffer->getHeight() == front.requested_h) 590bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 5919e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if ((front.w != front.requested_w) || 5929e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian (front.h != front.requested_h)) 5939e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian { 5949e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // Here we pretend the transaction happened by updating the 5959e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // current and drawing states. Drawing state is only accessed 5969e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // in this thread, no need to have it locked 5979e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editDraw(mDrawingState); 5989e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.w = editDraw.requested_w; 5999e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.h = editDraw.requested_h; 6009e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 6019e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // We also need to update the current state so that we don't 6029e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // end-up doing too much work during the next transaction. 6039e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // NOTE: We actually don't need hold the transaction lock here 6049e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // because State::w and State::h are only accessed from 6059e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this thread 6069e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editTemp(currentState()); 6079e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.w = editDraw.w; 6089e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.h = editDraw.h; 6099e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 6109e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // recompute visible region 6119e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian recomputeVisibleRegions = true; 6129e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 61346b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian 6149e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // we now have the correct size, unfreeze the screen 6159e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mFreezeLock.clear(); 6169e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 617e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 618e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the crop region 619e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian setBufferCrop( lcblk->getCrop(buf) ); 620e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 621e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian // get the transformation 622e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian setBufferTransform( lcblk->getTransform(buf) ); 623e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian 6249e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } else { 6259e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this should not happen unless we ran out of memory while 6269e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // allocating the buffer. we're hoping that things will get back 6279e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // to normal the next time the app tries to draw into this buffer. 6289e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // meanwhile, pretend the screen didn't update. 6299e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 6307cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian } 6317cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 632e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian if (lcblk->getQueuedCount()) { 633e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian // signal an event if we have more buffers waiting 634e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian mFlinger->signalEvent(); 635e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 637a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 638a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 639a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 640a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 641a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * for instance, a degenerate case could be that the user did an empty 642a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * update but repainted the buffer with appropriate content (after a 643a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * resize for instance). 644a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian */ 645a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian reloadTexture( mPostedDirtyRegion ); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6675469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian if (visibleRegionScreen.isEmpty()) { 6685469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian // an invisible layer should not hold a freeze-lock 6699bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian // (because it may never be updated and therefore never release it) 6705469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian mFreezeLock.clear(); 6715469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6749bce8737f2f7581ade57445286aa150de051ff89Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 6759bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian{ 6769bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 6779bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 6787623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 6797623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 6807623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian uint32_t totalTime = 0; 6817623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 6827623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 6837623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian totalTime= stats.totalTime; 6847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result.append( lcblk->dump(" ") ); 6857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 6867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6879bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 6889bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 6899bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w0=0, h0=0, s0=0; 6909bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w1=0, h1=0, s1=0; 6919bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf0 != 0) { 6929bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w0 = buf0->getWidth(); 6939bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h0 = buf0->getHeight(); 6949bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s0 = buf0->getStride(); 6959bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 6969bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf1 != 0) { 6979bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w1 = buf1->getWidth(); 6989bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h1 = buf1->getHeight(); 6999bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s1 = buf1->getStride(); 7009bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 7019bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian snprintf(buffer, SIZE, 7029bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian " " 7039bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 704025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian " freezeLock=%p, bypass=%d, dq-q-time=%u us\n", 7057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mFormat, w0, h0, s0, w1, h1, s1, 706025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian getFreezeLock().get(), mBypassState, totalTime); 7079bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 7089bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian result.append(buffer); 7099bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian} 7109bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 7111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 7121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 7137623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::ClientRef() 7145e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0), mToken(-1) { 7157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7177623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::~ClientRef() { 7187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::ClientRef::getToken() const { 7217623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 7227623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mToken; 7237623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7247623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7255e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const { 7265e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian Mutex::Autolock _l(mLock); 7275e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClient.promote(); 7285e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 7295e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7307623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 7315e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian const sp<SharedBufferServer>& sharedClient, int32_t token) { 7327623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 7335e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7345e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian { // scope for strong mUserClient reference 7355e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<UserClient> userClient(mUserClient.promote()); 7365e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (mUserClient != 0 && mControlBlock != 0) { 7375e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock->setStatus(NO_INIT); 7385e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 7395e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 7405e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7417623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClient = uc; 7427623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mToken = token; 7435e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = sharedClient; 7447623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return NO_ERROR; 7457623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7467623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7477623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 7487623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClient.promote(); 7497623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// this class gives us access to SharedBufferServer safely 7527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// it makes sure the UserClient (and its associated shared memory) 7537623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// won't go away while we're accessing it. 7547623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref) 7555e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0) 7567623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 7577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(ref.mLock); 7587623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClientStrongRef = ref.mUserClient.promote(); 7597623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mUserClientStrongRef != 0) 7605e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = ref.mControlBlock; 7615e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 7625e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 7635e14010b1fc066dfcbc0a577d59492687c99667dMathias AgopianLayer::ClientRef::Access::~Access() 7645e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 7657623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 7667623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// --------------------------------------------------------------------------- 7687623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 7699f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 770898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 7717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mActiveBuffer(-1), mFailover(false) 772898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 773898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 774898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 775898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias AgopianLayer::BufferManager::~BufferManager() 7769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 7779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7789f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 779898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size) 780898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 781898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 782898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mNumBuffers = size; 783898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 7849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// only for debugging 7879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 7889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mBufferData[index].buffer; 7899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 7929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mActiveBuffer = index; 7939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 7949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7959f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7969f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 7979f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mActiveBuffer; 7989f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7999f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8009f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 801898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Texture res; 8027623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mFailover || mActiveBuffer<0) { 803898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian res = mFailoverTexture; 804898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } else { 805898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 806898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 807898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return res; 8089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8099f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8109f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 8117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<GraphicBuffer> result; 8127623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian const ssize_t activeBuffer = mActiveBuffer; 8137623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (activeBuffer >= 0) { 8147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian BufferData const * const buffers = mBufferData; 8157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 8167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result = buffers[activeBuffer].buffer; 8177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 8187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return result; 8199f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8209f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8219f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 8229f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 823898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 8249f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer; 8259f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 826898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffer = buffers[index].buffer; 827898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = 0; 8289f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return buffer; 8299f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8309f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8319f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 8329f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 8339f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 834898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 8359f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 836898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = buffer; 837898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].texture.dirty = true; 8389f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 8399f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8409f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8419f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 8429f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 843898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 844898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian size_t num; 845898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian { // scope for the lock 846898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 847898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian num = mNumBuffers; 848898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 849898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[i].buffer = 0; 850898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 851898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 852898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 853898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 8549f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8559f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian destroyTexture(&mFailoverTexture, dpy); 8569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 8579f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8589f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 8609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 8619f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 8627623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = NO_INIT; 8637623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ssize_t index = mActiveBuffer; 8647623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (index >= 0) { 865781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (!mFailover) { 866781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian Image& texture(mBufferData[index].texture); 867781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = mTextureManager.initEglImage(&texture, dpy, buffer); 868781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 869781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // free all resources associated with using EGLImages. 870781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (err == NO_ERROR) { 871781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = false; 872781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mFailoverTexture, dpy); 873781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 874781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = true; 875781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian const size_t num = mNumBuffers; 876781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian for (size_t i=0 ; i<num ; i++) { 877781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 878781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } 879330dd304a471d260a73e342a240921c03c825f99Andreas Huber } 880781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 881781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // we failed once, don't try again 882781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = BAD_VALUE; 8839f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 8859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return err; 8869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::loadTexture( 8899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const Region& dirty, const GGLSurface& t) 8909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 8919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 8929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 8939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 894898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 895898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 896898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->name != -1U) { 897898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian glDeleteTextures(1, &tex->name); 898898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->name = -1U; 899898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 900898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 901898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 902898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 903898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 904898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 905898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 906898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 9079f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// --------------------------------------------------------------------------- 9089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 9096cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 910593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian const sp<Layer>& owner) 911593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 9126cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 9136cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 9146cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 9156cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 9161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 9171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 9181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 9192be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 9202be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 9211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 9226950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 9231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 9241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 925898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 926898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * requestBuffer() cannot be called from the main thread 927898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 928898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 929898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 9302be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 9311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 9321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 9331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 93659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 93759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian status_t err = DEAD_OBJECT; 93859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian sp<Layer> owner(getOwner()); 93959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian if (owner != 0) { 940898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 941898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * setBufferCount() cannot be called from the main thread 942898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 943898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 944898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 94559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian err = owner->setBufferCount(bufferCount); 94659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 94759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 94859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 94959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 954