Layer.cpp revision 51c70e3e41ee8bedc1d951a06a74202dafa13009
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), 602be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mWidth(0), mHeight(0), mFixedSize(false) 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer() 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 66898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // FIXME: must be called from the main UI thread 67898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 68898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.destroy(dpy); 69898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 707623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // we can use getUserClientUnsafe here because we know we're 717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian // single-threaded at that point. 727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (ourClient != 0) { 747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ourClient->detachLayer(this); 757623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 787623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient, 797623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedClient* sharedClient, int32_t token) 80593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian{ 815e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<SharedBufferServer> lcblk = new SharedBufferServer( 827623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sharedClient, token, mBufferManager.getDefaultBufferCount(), 837623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian getIdentity()); 84593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = mUserClientRef.setToken(userClient, lcblk, token); 865e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 875e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian LOGE_IF(err != NO_ERROR, 885e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian "ClientRef::setToken(%p, %p, %u) failed", 895e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian userClient.get(), lcblk.get(), token); 905e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 915e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (err == NO_ERROR) { 925e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian // we need to free the buffers associated with this surface 937623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 94593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 957623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return err; 967623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 97593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 987623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::getToken() const 997623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 1007623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClientRef.getToken(); 101593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian} 102593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 1035e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::getClient() const 1045e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 1055e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClientRef.getClient(); 1065e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 1075e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 1089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 1099f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// in the purgatory list 1109f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianvoid Layer::onRemoved() 1119f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 1127623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 1137623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 1147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 115593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // wake up the condition 116593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->setStatus(NO_INIT); 117593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 118248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian} 1199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 1201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSurface; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1256cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopianstatus_t Layer::ditch() 1266cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 127898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // NOTE: Called from the main UI thread 128898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 129a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian // the layer is not on screen anymore. free as much resources as possible 130f9b0e826689cca5ecbd40aa49f3ea7f7c73ad2a2Mathias Agopian mFreezeLock.clear(); 131898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 132898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 133898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.destroy(dpy); 134898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mSurface.clear(); 135898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 136898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 137898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mWidth = mHeight = 0; 1386cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian return NO_ERROR; 1396cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 1406cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 1416edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat format, uint32_t flags) 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 144cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // this surfaces pixel format 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // the display's pixel format 150cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 151967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian uint32_t const maxSurfaceDims = min( 152967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 153967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 154967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // never allow a surface larger than what our underlying GL implementation 155967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian // can handle. 156967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 157967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian return BAD_VALUE; 158967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian } 159967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 160cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian PixelFormatInfo displayInfo; 161cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 162351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 163351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian 1649779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 165d91ac98a8ead216b12af6df61d90229b74c7f0f6Mathias Agopian mReqFormat = format; 166967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian mWidth = w; 1679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 1686950e428feaccc8164b989ef64e771a99948797aMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 170967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian 171cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // we use the red index 172cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 173cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 174cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 175cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 176593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian mSurface = new SurfaceLayer(mFlinger, this); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1829f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 183083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian if (buffer == NULL) { 184083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // this situation can happen if we ran out of memory for instance. 185083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // not much we can do. continue to use whatever texture was bound 186083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // to this context. 187083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian return; 188083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian } 189083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian 190781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (mGLExtensions.haveDirectTexture()) { 1919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 1929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 1939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // not sure what we can do here... 1949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian goto slowpath; 1951473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 196781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 1971d211f8ee0b422a3a741c3f88246c7c72ce483b0Mathias Agopianslowpath: 1981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 1996950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 200dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 201dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian res, strerror(res), buffer.get()); 202dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian if (res == NO_ERROR) { 2039f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mBufferManager.loadTexture(dirty, t); 204dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian buffer->unlock(); 2051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2119f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Texture tex(mBufferManager.getActiveTexture()); 2129f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (tex.name == -1LU) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2142df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // in fact never been drawn into. This happens frequently with 2152df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // SurfaceView because the WindowManager can't know when the client 2162df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // has drawn the first time. 2172df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2182df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 2192df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // we just skip this update. 2202df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian 2212df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // figure out if there is something below us 2222df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region under; 2232df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 2242df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const size_t count = drawingLayers.size(); 2252df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian for (size_t i=0 ; i<count ; ++i) { 2262df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 2272df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 2282df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian break; 2292df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian under.orSelf(layer->visibleRegionScreen); 2302df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2312df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian // if not everything below us is covered, we plug the holes! 2322df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian Region holes(clip.subtract(under)); 2332df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian if (!holes.isEmpty()) { 234f8b4b4408cb864bf604608221eafa9d37323d348Mathias Agopian clearWithOpenGL(holes, 0, 0, 0, 1); 2352df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian drawWithOpenGL(clip, tex); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 241923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopianbool Layer::needsFiltering() const 242923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian{ 243923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 244923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian // NOTE: there is a race here, because mFixedSize is updated in a 245923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian // binder transaction. however, it doesn't really matter since it is 246923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian // evaluated each time we draw. To be perfectly correct, this flag 247923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian // would have to be associated with a buffer. 248923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian if (mFixedSize) 249923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return true; 250923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian } 251923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian return LayerBase::needsFiltering(); 252923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian} 253923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian 25459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 25559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::setBufferCount(int bufferCount) 25659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 2577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 2587623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 2597623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 26059751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian // oops, the client is already gone 26159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return DEAD_OBJECT; 26259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 26359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 264898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian // NOTE: lcblk->resize() is protected by an internal lock 265898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian status_t err = lcblk->resize(bufferCount); 266898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (err == NO_ERROR) 267898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mBufferManager.resize(bufferCount); 26859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 26959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 27059751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 27159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 2722be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, 2732be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 2742be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t usage) 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2766950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 277248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 2787623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 2792be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 2802be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 2812be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 2822be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return buffer; 2832be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 284248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // this ensures our client doesn't go away while we're accessing 285248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the shared area. 2867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 2877623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 2887623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 289248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops, the client is already gone 290248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 291248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 292248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 2931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 2949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 2959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 2969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 2971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 298248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 29951c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian status_t err = NO_ERROR; 3002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t w, h, f; 301248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian { // scope for the lock 302248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 3032be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); 3042be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian const bool formatChanged = mReqFormat != reqFormat; 3052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mReqWidth = reqWidth; 3062be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mReqHeight = reqHeight; 3072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mReqFormat = reqFormat; 3082be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mFixedSize = reqWidth && reqHeight; 3092be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian w = reqWidth ? reqWidth : mWidth; 3102be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian h = reqHeight ? reqHeight : mHeight; 3112be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian f = reqFormat ? reqFormat : mFormat; 3122be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (fixedSizeChanged || formatChanged) { 3132be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian lcblk->reallocateAllExcept(index); 3142be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 315248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 316248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 31751c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // here we have to reallocate a new buffer because the buffer could be 31851c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // used as the front buffer, or by a client in our process 31951c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian // (eg: status bar), and we can't release the handle under its feet. 3206950e428feaccc8164b989ef64e771a99948797aMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 32151c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian buffer = new GraphicBuffer(w, h, f, effectiveUsage); 32251c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian err = buffer->initCheck(); 3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 3259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 3269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 3279779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3299779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 330e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 331e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, index, w, h, buffer->handle); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 335248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 3362be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mBufferManager.attachBuffer(index, buffer); 3376edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 3389779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 3396edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 3406edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 3416950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3426950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 3436950e428feaccc8164b989ef64e771a99948797aMathias Agopian /* 3446950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for software rendering, but h/w composition 3456950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3466950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3476950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for h/w rendering and h/w composition 3486950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3496950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3506950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3516950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3526950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3536950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 3546950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3556950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mSecure) { 3566950e428feaccc8164b989ef64e771a99948797aMathias Agopian // secure buffer, don't store it into the GPU 3576950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3586950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3596950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 3606950e428feaccc8164b989ef64e771a99948797aMathias Agopian // it's allowed to modify the usage flags here, but generally 3616950e428feaccc8164b989ef64e771a99948797aMathias Agopian // the requested flags should be honored. 362aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian // request EGLImage for all buffers 363aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 3646950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 3656950e428feaccc8164b989ef64e771a99948797aMathias Agopian return usage; 3666950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 3676950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3732be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian const bool sizeChanged = (front.requested_w != temp.requested_w) || 3742be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian (front.requested_h != temp.requested_h); 3752be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 3762be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (sizeChanged) { 3779779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 3792be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 3802be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian this, 3812be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(temp.requested_w), int(temp.requested_h), 3822be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian int(front.requested_w), int(front.requested_h)); 3832be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 3842be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!isFixedSize()) { 3852be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // we're being resized and there is a freeze display request, 3862be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // acquire a freeze lock, so that the screen stays put 3872be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // until we've redrawn at the new size; this is to avoid 3882be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // glitches upon orientation changes. 3892be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (mFlinger->hasFreezeRequest()) { 3902be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // if the surface is hidden, don't try to acquire the 3912be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // freeze lock, since hidden surfaces may never redraw 3922be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 3932be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 3942be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3967cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 3972be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // this will make sure LayerBase::doTransaction doesn't update 3982be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // the drawing state's size 3992be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Layer::State& editDraw(mDrawingState); 4002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_w = temp.requested_w; 4012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian editDraw.requested_h = temp.requested_h; 402bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 4032be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size, form this point on, when the client request 4042be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // a buffer, it'll get the new size. 4052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 40670cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian 4077623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 4087623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 4097623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 410593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // all buffers need reallocation 411593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian lcblk->reallocateAll(); 412593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 4132be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } else { 4142be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian // record the new size 4152be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian setBufferSize(temp.requested_w, temp.requested_h); 4162be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4302be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) { 4319779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 4329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 4339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4362be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianbool Layer::isFixedSize() const { 4372be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian Mutex::Autolock _l(mLock); 4382be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian return mFixedSize; 4392be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian} 4402be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4477623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 4487623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 4497623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (!lcblk) { 450593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian // client died 451593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian recomputeVisibleRegions = true; 452593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian return; 453593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 454593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian 4559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 4569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf == NOT_ENOUGH_DATA) { 4579f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // NOTE: This is not an error, it simply means there is nothing to 4589f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian // retire. The buffer is locked because we will use it 4599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 4639f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (buf < NO_ERROR) { 4647623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 4659e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 4669e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian return; 4679e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 4689e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 4699779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 4709f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 4717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 4729f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mPostedDirtyRegion.clear(); 4739f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return; 4749f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // get the dirty region 4776950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 4789e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer != NULL) { 4799e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // compute the posted region 4809e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 4819e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 4829e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 4839e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // update the layer size and release freeze-lock 4849e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian const Layer::State& front(drawingState()); 4859e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 4869e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian newFrontBuffer->getHeight() == front.requested_h) 487bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 4889e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian if ((front.w != front.requested_w) || 4899e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian (front.h != front.requested_h)) 4909e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian { 4919e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // Here we pretend the transaction happened by updating the 4929e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // current and drawing states. Drawing state is only accessed 4939e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // in this thread, no need to have it locked 4949e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editDraw(mDrawingState); 4959e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.w = editDraw.requested_w; 4969e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editDraw.h = editDraw.requested_h; 4979e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 4989e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // We also need to update the current state so that we don't 4999e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // end-up doing too much work during the next transaction. 5009e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // NOTE: We actually don't need hold the transaction lock here 5019e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // because State::w and State::h are only accessed from 5029e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this thread 5039e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian Layer::State& editTemp(currentState()); 5049e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.w = editDraw.w; 5059e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian editTemp.h = editDraw.h; 5069e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian 5079e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // recompute visible region 5089e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian recomputeVisibleRegions = true; 5099e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 51046b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian 5119e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // we now have the correct size, unfreeze the screen 5129e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mFreezeLock.clear(); 5139e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } 5149e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian } else { 5159e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // this should not happen unless we ran out of memory while 5169e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // allocating the buffer. we're hoping that things will get back 5179e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // to normal the next time the app tries to draw into this buffer. 5189e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian // meanwhile, pretend the screen didn't update. 5199e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian mPostedDirtyRegion.clear(); 5207cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian } 5217cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 522e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian if (lcblk->getQueuedCount()) { 523e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian // signal an event if we have more buffers waiting 524e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian mFlinger->signalEvent(); 525e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 527a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian /* a buffer was posted, so we need to call reloadTexture(), which 528a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * will update our internal data structures (eg: EGLImageKHR or 529a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * texture names). we need to do this even if mPostedDirtyRegion is 530a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * empty -- it's orthogonal to the fact that a new buffer was posted, 531a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * for instance, a degenerate case could be that the user did an empty 532a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * update but repainted the buffer with appropriate content (after a 533a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian * resize for instance). 534a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian */ 535a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian reloadTexture( mPostedDirtyRegion ); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5575469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian if (visibleRegionScreen.isEmpty()) { 5585469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian // an invisible layer should not hold a freeze-lock 5599bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian // (because it may never be updated and therefore never release it) 5605469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian mFreezeLock.clear(); 5615469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip() 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5667623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5687623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 569593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian int buf = mBufferManager.getActiveBufferIndex(); 5707623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (buf >= 0) { 5717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = lcblk->unlock( buf ); 5727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian LOGE_IF(err!=NO_ERROR, 5737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian "layer %p, buffer=%d wasn't locked!", 5747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian this, buf); 5757623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 576593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 5809bce8737f2f7581ade57445286aa150de051ff89Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 5819bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian{ 5829bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 5839bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 5847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ClientRef::Access sharedClient(mUserClientRef); 5857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferServer* lcblk(sharedClient.get()); 5867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian uint32_t totalTime = 0; 5877623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (lcblk) { 5887623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian SharedBufferStack::Statistics stats = lcblk->getStats(); 5897623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian totalTime= stats.totalTime; 5907623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result.append( lcblk->dump(" ") ); 5917623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 5927623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 5939bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf0(getBuffer(0)); 5949bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian sp<const GraphicBuffer> buf1(getBuffer(1)); 5959bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w0=0, h0=0, s0=0; 5969bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian uint32_t w1=0, h1=0, s1=0; 5979bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf0 != 0) { 5989bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w0 = buf0->getWidth(); 5999bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h0 = buf0->getHeight(); 6009bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s0 = buf0->getStride(); 6019bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 6029bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian if (buf1 != 0) { 6039bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian w1 = buf1->getWidth(); 6049bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian h1 = buf1->getHeight(); 6059bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian s1 = buf1->getStride(); 6069bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian } 6079bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian snprintf(buffer, SIZE, 6089bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian " " 6099bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 6109bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian " freezeLock=%p, dq-q-time=%u us\n", 6117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mFormat, w0, h0, s0, w1, h1, s1, 6127623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian getFreezeLock().get(), totalTime); 6139bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 6149bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian result.append(buffer); 6159bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian} 6169bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian 6171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 6181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 6197623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::ClientRef() 6205e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0), mToken(-1) { 6217623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6227623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6237623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::~ClientRef() { 6247623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6257623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6267623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::ClientRef::getToken() const { 6277623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 6287623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mToken; 6297623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6307623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6315e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const { 6325e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian Mutex::Autolock _l(mLock); 6335e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian return mUserClient.promote(); 6345e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 6355e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 6367623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 6375e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian const sp<SharedBufferServer>& sharedClient, int32_t token) { 6387623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 6395e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 6405e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian { // scope for strong mUserClient reference 6415e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian sp<UserClient> userClient(mUserClient.promote()); 6425e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian if (mUserClient != 0 && mControlBlock != 0) { 6435e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock->setStatus(NO_INIT); 6445e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 6455e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian } 6465e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 6477623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClient = uc; 6487623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mToken = token; 6495e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = sharedClient; 6507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return NO_ERROR; 6517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6537623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 6547623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return mUserClient.promote(); 6557623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6567623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// this class gives us access to SharedBufferServer safely 6587623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// it makes sure the UserClient (and its associated shared memory) 6597623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// won't go away while we're accessing it. 6607623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref) 6615e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian : mControlBlock(0) 6627623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{ 6637623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(ref.mLock); 6647623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mUserClientStrongRef = ref.mUserClient.promote(); 6657623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mUserClientStrongRef != 0) 6665e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian mControlBlock = ref.mControlBlock; 6675e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian} 6685e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian 6695e14010b1fc066dfcbc0a577d59492687c99667dMathias AgopianLayer::ClientRef::Access::~Access() 6705e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{ 6717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian} 6727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// --------------------------------------------------------------------------- 6747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian 6759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm) 676898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 6777623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian mActiveBuffer(-1), mFailover(false) 678898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 679898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 680898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 681898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias AgopianLayer::BufferManager::~BufferManager() 6829f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 6839f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 6849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 685898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size) 686898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 687898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 688898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mNumBuffers = size; 689898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 6909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 6919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 6929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// only for debugging 6939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 6949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mBufferData[index].buffer; 6959f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 6969f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 6979f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 6989f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian mActiveBuffer = index; 6999f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 7009f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7019f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7029f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const { 7039f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mActiveBuffer; 7049f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7059f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7069f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianTexture Layer::BufferManager::getActiveTexture() const { 707898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Texture res; 7087623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (mFailover || mActiveBuffer<0) { 709898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian res = mFailoverTexture; 710898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } else { 711898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 712898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 713898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return res; 7149f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7159f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7169f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 7177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian sp<GraphicBuffer> result; 7187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian const ssize_t activeBuffer = mActiveBuffer; 7197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (activeBuffer >= 0) { 7207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian BufferData const * const buffers = mBufferData; 7217623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian Mutex::Autolock _l(mLock); 7227623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian result = buffers[activeBuffer].buffer; 7237623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian } 7247623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian return result; 7259f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7269f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7279f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 7289f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 729898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 7309f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian sp<GraphicBuffer> buffer; 7319f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 732898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffer = buffers[index].buffer; 733898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = 0; 7349f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return buffer; 7359f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7369f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7379f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index, 7389f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 7399f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 740898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 7419f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian Mutex::Autolock _l(mLock); 742898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].buffer = buffer; 743898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[index].texture.dirty = true; 7449f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 7459f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7469f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7479f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy) 7489f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 749898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian BufferData* const buffers = mBufferData; 750898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian size_t num; 751898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian { // scope for the lock 752898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian Mutex::Autolock _l(mLock); 753898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian num = mNumBuffers; 754898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 755898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian buffers[i].buffer = 0; 756898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 757898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 758898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian for (size_t i=0 ; i<num ; i++) { 759898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian destroyTexture(&buffers[i].texture, dpy); 7609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 7619f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian destroyTexture(&mFailoverTexture, dpy); 7629f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return NO_ERROR; 7639f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7649f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7659f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 7669f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const sp<GraphicBuffer>& buffer) 7679f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 7687623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian status_t err = NO_INIT; 7697623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian ssize_t index = mActiveBuffer; 7707623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian if (index >= 0) { 771781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (!mFailover) { 772781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian Image& texture(mBufferData[index].texture); 773781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = mTextureManager.initEglImage(&texture, dpy, buffer); 774781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // if EGLImage fails, we switch to regular texture mode, and we 775781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // free all resources associated with using EGLImages. 776781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (err == NO_ERROR) { 777781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = false; 778781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mFailoverTexture, dpy); 779781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 780781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian mFailover = true; 781781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian const size_t num = mNumBuffers; 782781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian for (size_t i=0 ; i<num ; i++) { 783781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian destroyTexture(&mBufferData[i].texture, dpy); 784781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } 785330dd304a471d260a73e342a240921c03c825f99Andreas Huber } 786781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } else { 787781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian // we failed once, don't try again 788781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian err = BAD_VALUE; 7899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 7909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian } 7919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return err; 7929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 7949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::loadTexture( 7959f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian const Region& dirty, const GGLSurface& t) 7969f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{ 7979f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 7989f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian} 7999f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 800898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 801898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{ 802898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->name != -1U) { 803898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian glDeleteTextures(1, &tex->name); 804898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->name = -1U; 805898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 806898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian if (tex->image != EGL_NO_IMAGE_KHR) { 807898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian eglDestroyImageKHR(dpy, tex->image); 808898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian tex->image = EGL_NO_IMAGE_KHR; 809898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian } 810898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian return NO_ERROR; 811898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian} 812898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian 8139f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// --------------------------------------------------------------------------- 8149f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian 8156cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 816593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian const sp<Layer>& owner) 817593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian : Surface(flinger, owner->getIdentity(), owner) 8186cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 8196cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 8206cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 8216cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 8221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 8231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 8241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 8252be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 8262be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 8271473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 8286950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 8291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 8301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 831898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 832898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * requestBuffer() cannot be called from the main thread 833898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 834898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 835898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 8362be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian buffer = owner->requestBuffer(index, w, h, format, usage); 8371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 8381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 8391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 84259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{ 84359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian status_t err = DEAD_OBJECT; 84459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian sp<Layer> owner(getOwner()); 84559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian if (owner != 0) { 846898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian /* 847898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * setBufferCount() cannot be called from the main thread 848898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * as it could cause a dead-lock, since it may have to wait 849898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian * on conditions updated my the main thread. 850898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian */ 85159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian err = owner->setBufferCount(bufferCount); 85259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian } 85359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian return err; 85459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian} 85559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 860