Layer.cpp revision 9779b221e999583ff89e0dfc40e56398737adbb3
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 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/PixelFormat.h> 291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <ui/Surface.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#include "Buffer.h" 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clz.h" 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Layer.h" 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SurfaceFlinger.h" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_RESIZE 0 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const Layer::typeID = "Layer"; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509779b221e999583ff89e0dfc40e56398737adbb3Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display, 519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian const sp<Client>& c, int32_t i) 529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian : LayerBaseClient(flinger, display, c, i), lcblk(NULL), 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSecure(false), 549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mNeedsBlending(true) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no OpenGL operation is possible here, since we might not be 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in the OpenGL thread. 589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS); 599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFrontBufferIndex = lcblk->getFrontBuffer(); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer() 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 64a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian destroy(); 65a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian // the actual buffers will be destroyed here 669779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian delete lcblk; 679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 68a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian} 69a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian 70a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopianvoid Layer::destroy() 71a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian{ 729779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].name != -1U) { 7481b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian glDeleteTextures(1, &mTextures[i].name); 75a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].name = -1U; 761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].image != EGL_NO_IMAGE_KHR) { 781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglDestroyImageKHR(dpy, mTextures[i].image); 80a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mBuffers[i].clear(); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 84359140c171f67b9b29a1beae9743b49d0759414bMathias Agopian mSurface.clear(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSurface; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 926cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopianstatus_t Layer::ditch() 936cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 94a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian // the layer is not on screen anymore. free as much resources as possible 95a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian destroy(); 966cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian return NO_ERROR; 976cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 986cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 996edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat format, uint32_t flags) 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian uint32_t bufferFlags = 0; 1071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (flags & ISurfaceComposer::eSecure) 1081473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian bufferFlags |= Buffer::SECURE; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 1119779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 1129779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 1131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mSecure = (bufferFlags & Buffer::SECURE) ? true : false; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 1159779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mBufferFlags = bufferFlags; 1169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 1179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mBuffers[i] = new Buffer(); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1196cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 1269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian sp<Buffer> buffer(getFrontBuffer()); 127dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { 1281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int index = mFrontBufferIndex; 1291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (LIKELY(!mTextures[index].dirty)) { 1301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glBindTexture(GL_TEXTURE_2D, mTextures[index].name); 1311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // we need to recreate the texture 1331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 1341473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // create the new texture name if needed 1361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(mTextures[index].name == -1U)) { 1371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].name = createTexture(); 1381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glBindTexture(GL_TEXTURE_2D, mTextures[index].name); 1401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // free the previous image 1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[index].image != EGL_NO_IMAGE_KHR) { 1441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglDestroyImageKHR(dpy, mTextures[index].image); 1451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].image = EGL_NO_IMAGE_KHR; 1461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // construct an EGL_NATIVE_BUFFER_ANDROID 1491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); 1501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // create the new EGLImageKHR 1521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const EGLint attrs[] = { 1531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 1541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGL_NONE, EGL_NONE 1551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian }; 1561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].image = eglCreateImageKHR( 1571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, 1581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian (EGLClientBuffer)clientBuf, attrs); 1591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR, 1611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian "eglCreateImageKHR() failed. err=0x%4x", 1621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglGetError()); 1631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[index].image != EGL_NO_IMAGE_KHR) { 1651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 1661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian (GLeglImageOES)mTextures[index].image); 1671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint error = glGetError(); 1681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(error != GL_NO_ERROR)) { 1691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // this failed, for instance, because we don't support 1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // NPOT. 1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // FIXME: do something! 1721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 1731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Everything went okay! 175999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].dirty = false; 176999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].width = clientBuf->width; 177999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].height = clientBuf->height; 1781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1821473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 183dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); 184dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 185dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian res, strerror(res), buffer.get()); 186dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian if (res == NO_ERROR) { 1871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(mTextures[0].name == -1U)) { 1881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[0].name = createTexture(); 1891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 190999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian loadTexture(&mTextures[0], mTextures[0].name, dirty, t); 191dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian buffer->unlock(); 1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? 2001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mFrontBufferIndex : 0; 2011473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLuint textureName = mTextures[index].name; 2021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(textureName == -1LU)) { 2039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian //LOGW("Layer %p doesn't have a texture", this); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in fact never been drawn into. this happens frequently with 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // SurfaceView. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearWithOpenGL(clip); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 211999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian drawWithOpenGL(clip, mTextures[index]); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopiansp<SurfaceBuffer> Layer::requestBuffer(int index, int usage) 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 2179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 2189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 2199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 2201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * 2219779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 2229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 2239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer cannot become the front buffer under our feet, since we're called 2249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * from Surface::dequeue() 2251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 2269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->assertReallocate(index); 2279779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 2281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2299779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 2309779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian uint32_t w = mWidth; 2319779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian uint32_t h = mHeight; 2321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian sp<Buffer>& buffer(mBuffers[index]); 2349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (buffer->getStrongCount() == 1) { 2359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags); 2369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } else { 2379779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // here we have to reallocate a new buffer because we could have a 2389779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // client in our process with a reference to it (eg: status bar), 2399779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // and we can't release the handle under its feet. 2409779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer.clear(); 2419779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer = new Buffer(w, h, mFormat, usage, mBufferFlags); 2429779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian err = buffer->initCheck(); 2431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 2469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 2479779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 2489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2509779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 2519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d", 2529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 2569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // texture is now dirty... 2579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mTextures[index].dirty = true; 2586edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 2599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 2606edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 2616edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Index of the back buffer 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (backbufferChanged) { 2719779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 2739779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "resize (layer=%p), requested (%dx%d), " 2749779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "drawing (%d,%d), (%dx%d), (%dx%d)", 2759779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, int(temp.w), int(temp.h), 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int(drawingState().w), int(drawingState().h), 2779779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()), 2789779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight())); 2799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // record the new size, form this point on, when the client request a 2819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // buffer, it'll get the new size. 2829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian setDrawingSize(temp.w, temp.h); 2839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2849779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // all buffers need reallocation 2859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian lcblk->reallocate(); 2869779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2879779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // recompute the visible region 2889779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // FIXME: ideally we would do that only when we have received 2899779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // a buffer of the right size 2909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian flags |= Layer::eVisibleRegion; 2919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this->contentDirty = true; 2929779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#if 0 2949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // FIXME: handle freeze lock 2959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we're being resized and there is a freeze display request, 2969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // acquire a freeze lock, so that the screen stays put 2979779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // until we've redrawn at the new size; this is to avoid 2989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // glitches upon orientation changes. 2999779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (mFlinger->hasFreezeRequest()) { 3009779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // if the surface is hidden, don't try to acquire the 3019779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // freeze lock, since hidden surfaces may never redraw 3029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 3039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#endif 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) { 3219779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 3339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (buf < NO_ERROR) { 3349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian //LOGW("nothing to retire (%s)", strerror(-buf)); 3359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // NOTE: here the buffer is locked because we will used 3369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 3409779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 3419779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFrontBufferIndex = buf; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // get the dirty region 3449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian sp<Buffer> newFrontBuffer(getBuffer(buf)); 3459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 3469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // FIXME: signal an event if we have more buffers waiting 3499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // mFlinger->signalEvent(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian reloadTexture( mPostedDirtyRegion ); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip() 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3779779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->unlock( mFrontBufferIndex ); 3789779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err!=NO_ERROR, 3799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "layer %p, buffer=%d wasn't locked!", 3809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, mFrontBufferIndex); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 3841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 3856cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 3866cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian SurfaceID id, const sp<Layer>& owner) 3876cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 3886cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 3896cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 3906cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 3916cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 3921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 3931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 3941473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopiansp<SurfaceBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 3961473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 3979779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian sp<SurfaceBuffer> buffer; 3981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 3991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 4009779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(uint32_t(index)>=NUM_BUFFERS, 4019779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "getBuffer() index (%d) out of range", index); 4029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (uint32_t(index) < NUM_BUFFERS) { 4039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer = owner->requestBuffer(index, usage); 4049779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } 4051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 4061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 4071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 413