Layer.cpp revision 6950e428feaccc8164b989ef64e771a99948797a
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> 301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <ui/Surface.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 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) 52248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian : LayerBaseClient(flinger, display, c, i), 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSecure(false), 54cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsBlending(true), 55cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering(false) 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no OpenGL operation is possible here, since we might not be 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in the OpenGL thread. 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 66248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian} 679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 68a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopianvoid Layer::destroy() 69a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian{ 709779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].name != -1U) { 7281b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian glDeleteTextures(1, &mTextures[i].name); 73a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].name = -1U; 741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].image != EGL_NO_IMAGE_KHR) { 761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglDestroyImageKHR(dpy, mTextures[i].image); 78a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 80248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mBuffers[i].clear(); 82248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mWidth = mHeight = 0; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 842e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias 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 952e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias 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{ 102cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // this surfaces pixel format 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 107cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // the display's pixel format 108cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 109cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian PixelFormatInfo displayInfo; 110cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 111cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 1129779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 1139779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 1149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 1156950e428feaccc8164b989ef64e771a99948797aMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 117cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 118cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // we use the red index 119cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 120cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 121cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 122cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 1239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 1246950e428feaccc8164b989ef64e771a99948797aMathias Agopian mBuffers[i] = new GraphicBuffer(); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1266cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 1336950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer(getFrontBuffer()); 1346950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (LIKELY((mFlags & DisplayHardware::DIRECT_TEXTURE) && 1356950e428feaccc8164b989ef64e771a99948797aMathias Agopian (buffer->usage & GRALLOC_USAGE_HW_TEXTURE))) { 1361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int index = mFrontBufferIndex; 1371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (LIKELY(!mTextures[index].dirty)) { 1381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glBindTexture(GL_TEXTURE_2D, mTextures[index].name); 1391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // we need to recreate the texture 1411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 1421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // create the new texture name if needed 1441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(mTextures[index].name == -1U)) { 1451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].name = createTexture(); 1461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glBindTexture(GL_TEXTURE_2D, mTextures[index].name); 1481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // free the previous image 1511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[index].image != EGL_NO_IMAGE_KHR) { 1521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglDestroyImageKHR(dpy, mTextures[index].image); 1531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].image = EGL_NO_IMAGE_KHR; 1541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // construct an EGL_NATIVE_BUFFER_ANDROID 1571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); 1581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // create the new EGLImageKHR 1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const EGLint attrs[] = { 1611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 1621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGL_NONE, EGL_NONE 1631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian }; 1641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[index].image = eglCreateImageKHR( 1651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, 1661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian (EGLClientBuffer)clientBuf, attrs); 1671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR, 1691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian "eglCreateImageKHR() failed. err=0x%4x", 1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglGetError()); 1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[index].image != EGL_NO_IMAGE_KHR) { 1731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 1741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian (GLeglImageOES)mTextures[index].image); 1751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint error = glGetError(); 1761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(error != GL_NO_ERROR)) { 1771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // this failed, for instance, because we don't support 1781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // NPOT. 1791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // FIXME: do something! 180ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian LOGD("layer=%p, glEGLImageTargetTexture2DOES(%p) " 18164a7c6bf5b73c1a401cb2aa8dfad3898166ae326Mathias Agopian "failed err=0x%04x", 18264a7c6bf5b73c1a401cb2aa8dfad3898166ae326Mathias Agopian this, mTextures[index].image, error); 1831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mFlags &= ~DisplayHardware::DIRECT_TEXTURE; 1841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Everything went okay! 1866950e428feaccc8164b989ef64e771a99948797aMathias Agopian mTextures[index].NPOTAdjust = false; 187999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].dirty = false; 188999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].width = clientBuf->width; 189999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian mTextures[index].height = clientBuf->height; 1901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1911473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 1946950e428feaccc8164b989ef64e771a99948797aMathias Agopian for (int i=0 ; i<NUM_BUFFERS ; i++) 1956950e428feaccc8164b989ef64e771a99948797aMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 1966950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 1986950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 199dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 200dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian res, strerror(res), buffer.get()); 2016950e428feaccc8164b989ef64e771a99948797aMathias Agopian 202dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian if (res == NO_ERROR) { 2031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(mTextures[0].name == -1U)) { 2041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian mTextures[0].name = createTexture(); 2056950e428feaccc8164b989ef64e771a99948797aMathias Agopian mTextures[0].width = 0; 2066950e428feaccc8164b989ef64e771a99948797aMathias Agopian mTextures[0].height = 0; 2071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2086950e428feaccc8164b989ef64e771a99948797aMathias Agopian loadTexture(&mTextures[0], dirty, t); 209dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian buffer->unlock(); 2101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2176950e428feaccc8164b989ef64e771a99948797aMathias Agopian int index = mFrontBufferIndex; 2186950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mTextures[index].image == EGL_NO_IMAGE_KHR) 2196950e428feaccc8164b989ef64e771a99948797aMathias Agopian index = 0; 2201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLuint textureName = mTextures[index].name; 2211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(textureName == -1LU)) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in fact never been drawn into. this happens frequently with 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // SurfaceView. 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearWithOpenGL(clip); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 228999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian drawWithOpenGL(clip, mTextures[index]); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2316950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage) 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2336950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 234248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 235248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // this ensures our client doesn't go away while we're accessing 236248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the shared area. 237248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian sp<Client> ourClient(client.promote()); 238248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (ourClient == 0) { 239248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops, the client is already gone 240248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 241248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 242248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 2431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 2449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 2459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 2469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 2471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * 2489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 2499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 2509779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer cannot become the front buffer under our feet, since we're called 2519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * from Surface::dequeue() 2521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 2539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->assertReallocate(index); 2549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 255248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (err != NO_ERROR) { 256248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the surface may have died 257248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 258248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 259248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 260248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian uint32_t w, h; 261248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian { // scope for the lock 262248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 263248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian w = mWidth; 264248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian h = mHeight; 265248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian buffer = mBuffers[index]; 266ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian 267ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian // destroy() could have been called before we get here, we log it 268ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian // because it's uncommon, and the code below should handle it 269ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian LOGW_IF(buffer==0, 270ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian "mBuffers[%d] is null (mWidth=%d, mHeight=%d)", 271ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian index, w, h); 272ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian 273248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mBuffers[index].clear(); 274248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 275248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 2766950e428feaccc8164b989ef64e771a99948797aMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 277ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 2786950e428feaccc8164b989ef64e771a99948797aMathias Agopian err = buffer->reallocate(w, h, mFormat, effectiveUsage); 2799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } else { 2809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // here we have to reallocate a new buffer because we could have a 2819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // client in our process with a reference to it (eg: status bar), 2829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // and we can't release the handle under its feet. 2839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer.clear(); 2846950e428feaccc8164b989ef64e771a99948797aMathias Agopian buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); 2859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian err = buffer->initCheck(); 2861473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2879779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 2889779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 2899779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 2909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 2919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 294e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 295e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, index, w, h, buffer->handle); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 299248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 300248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (mWidth && mHeight) { 301248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // and we have new buffer 302248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mBuffers[index] = buffer; 303248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // texture is now dirty... 304248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mTextures[index].dirty = true; 305248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } else { 306248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops we got killed while we were allocating the buffer 307248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian buffer.clear(); 308248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 3096edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 3109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 3116edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 3126edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 3136950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3146950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 3156950e428feaccc8164b989ef64e771a99948797aMathias Agopian /* 3166950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for software rendering, but h/w composition 3176950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3186950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3196950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for h/w rendering and h/w composition 3206950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3216950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3226950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3236950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3246950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3256950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 3266950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3276950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mSecure) { 3286950e428feaccc8164b989ef64e771a99948797aMathias Agopian // secure buffer, don't store it into the GPU 3296950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3306950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3316950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 3326950e428feaccc8164b989ef64e771a99948797aMathias Agopian // it's allowed to modify the usage flags here, but generally 3336950e428feaccc8164b989ef64e771a99948797aMathias Agopian // the requested flags should be honored. 3346950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 3356950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 3366950e428feaccc8164b989ef64e771a99948797aMathias Agopian return usage; 3376950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 3386950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 344e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian if ((front.requested_w != temp.requested_w) || 345e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian (front.requested_h != temp.requested_h)) { 3469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 3489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "resize (layer=%p), requested (%dx%d), " 3499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "drawing (%d,%d), (%dx%d), (%dx%d)", 350e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, 351e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian int(temp.requested_w), int(temp.requested_h), 352e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian int(front.requested_w), int(front.requested_h), 3539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()), 3549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight())); 3559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we're being resized and there is a freeze display request, 3579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // acquire a freeze lock, so that the screen stays put 3589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // until we've redrawn at the new size; this is to avoid 3599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // glitches upon orientation changes. 3609779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (mFlinger->hasFreezeRequest()) { 3619779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // if the surface is hidden, don't try to acquire the 3629779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // freeze lock, since hidden surfaces may never redraw 3639779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 3649779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3677cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 368bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // this will make sure LayerBase::doTransaction doesn't update 369bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // the drawing state's size 370bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editDraw(mDrawingState); 371bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.requested_w = temp.requested_w; 372bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.requested_h = temp.requested_h; 373bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 37470cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian // record the new size, form this point on, when the client request a 37570cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian // buffer, it'll get the new size. 37670cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian setDrawingSize(temp.requested_w, temp.requested_h); 37770cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian 3787cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian // all buffers need reallocation 3797cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian lcblk->reallocate(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) { 3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 3969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4059779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 4069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (buf < NO_ERROR) { 4079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian //LOGW("nothing to retire (%s)", strerror(-buf)); 4089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // NOTE: here the buffer is locked because we will used 4099779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4139779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 4149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFrontBufferIndex = buf; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // get the dirty region 4176950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 4189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 4199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4217cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian const Layer::State& front(drawingState()); 422bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 423bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 424bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 425bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian if ((front.w != front.requested_w) || 426bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian (front.h != front.requested_h)) 427bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 428bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // Here we pretend the transaction happened by updating the 429bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // current and drawing states. Drawing state is only accessed 430bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // in this thread, no need to have it locked 431bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editDraw(mDrawingState); 432bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.w = editDraw.requested_w; 433bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.h = editDraw.requested_h; 434bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 435bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // We also need to update the current state so that we don't 436bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // end-up doing too much work during the next transaction. 437bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 438bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // because State::w and State::h are only accessed from 439bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // this thread 440bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editTemp(currentState()); 441bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editTemp.w = editDraw.w; 442bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editTemp.h = editDraw.h; 443bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 444bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // recompute visible region 445bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian recomputeVisibleRegions = true; 446bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 447bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // we now have the correct size, unfreeze the screen 448bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian mFreezeLock.clear(); 449bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian } 4507cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian } 4517cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 4529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // FIXME: signal an event if we have more buffers waiting 4539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // mFlinger->signalEvent(); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4556950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (!mPostedDirtyRegion.isEmpty()) { 4566950e428feaccc8164b989ef64e771a99948797aMathias Agopian reloadTexture( mPostedDirtyRegion ); 4576950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip() 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->unlock( mFrontBufferIndex ); 4849779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err!=NO_ERROR, 4859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "layer %p, buffer=%d wasn't locked!", 4869779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, mFrontBufferIndex); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 4901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4916cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 4926cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian SurfaceID id, const sp<Layer>& owner) 4936cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 4946cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 4956cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 4966cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 4976cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 4981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 4991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 5001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 5016950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 5021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 5036950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 5041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 5051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 5069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(uint32_t(index)>=NUM_BUFFERS, 5079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "getBuffer() index (%d) out of range", index); 5089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (uint32_t(index) < NUM_BUFFERS) { 5099779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer = owner->requestBuffer(index, usage); 5109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } 5111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 5121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 5131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 519