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), 54351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian mNoEGLImageForSwBuffers(false), 55cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsBlending(true), 56cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering(false) 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no OpenGL operation is possible here, since we might not be 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in the OpenGL thread. 609779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFrontBufferIndex = lcblk->getFrontBuffer(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer() 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 65a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian destroy(); 66a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian // the actual buffers will be destroyed here 67248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian} 689779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 69a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopianvoid Layer::destroy() 70a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian{ 719779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].name != -1U) { 7381b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian glDeleteTextures(1, &mTextures[i].name); 74a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].name = -1U; 751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (mTextures[i].image != EGL_NO_IMAGE_KHR) { 771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian eglDestroyImageKHR(dpy, mTextures[i].image); 79a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 81248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mBuffers[i].clear(); 83248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mWidth = mHeight = 0; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 852e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias Agopian mSurface.clear(); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSurface; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 936cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopianstatus_t Layer::ditch() 946cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 95a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian // the layer is not on screen anymore. free as much resources as possible 96f9b0e826689cca5ecbd40aa49f3ea7f7c73ad2a2Mathias Agopian mFreezeLock.clear(); 972e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias Agopian destroy(); 986cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian return NO_ERROR; 996cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 1006cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 1016edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat format, uint32_t flags) 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 104cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // this surfaces pixel format 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormatInfo info; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) return err; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // the display's pixel format 110cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 111cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian PixelFormatInfo displayInfo; 112cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian getPixelFormatInfo(hw.getFormat(), &displayInfo); 113351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian const uint32_t hwFlags = hw.getFlags(); 114351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian 1159779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFormat = format; 1169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 1179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 1186950e428feaccc8164b989ef64e771a99948797aMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 120351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS); 121351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian 122cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian // we use the red index 123cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 124cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 125cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian mNeedsDithering = layerRedsize > displayRedSize; 126cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian 1279779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 1286950e428feaccc8164b989ef64e771a99948797aMathias Agopian mBuffers[i] = new GraphicBuffer(); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1306cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 1374961c959aebac31991fd7653853d47dfd79d3472Mathias Agopian sp<GraphicBuffer> buffer(getFrontBufferLocked()); 138083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian if (buffer == NULL) { 139083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // this situation can happen if we ran out of memory for instance. 140083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // not much we can do. continue to use whatever texture was bound 141083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian // to this context. 142083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian return; 143083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian } 144083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian 145083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian const int index = mFrontBufferIndex; 146382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian 147382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian // create the new texture name if needed 148382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (UNLIKELY(mTextures[index].name == -1U)) { 149382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mTextures[index].name = createTexture(); 150382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mTextures[index].width = 0; 151382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mTextures[index].height = 0; 152382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 153382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian 1549042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer 155382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (mFlags & DisplayHardware::DIRECT_TEXTURE) { 156382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) { 157382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (mTextures[index].dirty) { 1589042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian initializeEglImage(buffer, &mTextures[index]); 159382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 161382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width || 162382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mHybridBuffer->height != buffer->height)) { 163382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mHybridBuffer.clear(); 164382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mHybridBuffer = new GraphicBuffer( 165382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian buffer->width, buffer->height, buffer->format, 166382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN | 167382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian GraphicBuffer::USAGE_HW_TEXTURE); 1689042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian initializeEglImage( 169382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian mHybridBuffer, &mTextures[0]); 1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 172382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian GGLSurface t; 173382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 174382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 175382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian res, strerror(res), buffer.get()); 176382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (res == NO_ERROR) { 177382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian Texture* const texture(&mTextures[0]); 178382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian 179382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian glBindTexture(GL_TEXTURE_2D, texture->name); 180382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian 181382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian sp<GraphicBuffer> buf(mHybridBuffer); 182382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian void* vaddr; 183382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr); 184382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (res == NO_ERROR) { 185382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian int bpp = 0; 186382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian switch (t.format) { 187382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_RGB_565: 188382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_RGBA_4444: 189382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian bpp = 2; 190382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian break; 191382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_RGBA_8888: 192382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_RGBX_8888: 193382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian bpp = 4; 194382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian break; 195382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_YCbCr_422_SP: 196382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian case GGL_PIXEL_FORMAT_YCbCr_420_SP: 197382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian // just show the Y plane of YUV buffers 198382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian bpp = 1; 199382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian break; 200382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian default: 201382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian // oops, we don't handle this format! 202382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian LOGE("layer %p, texture=%d, using format %d, which is not " 203382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian "supported by the GL", this, texture->name, t.format); 204382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 205382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (bpp) { 206382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian const Rect bounds(dirty.getBounds()); 207382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian size_t src_stride = t.stride; 208382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian size_t dst_stride = buf->stride; 209382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian if (src_stride == dst_stride && 210382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian bounds.width() == t.width && 211382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian bounds.height() == t.height) 212382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian { 213382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian memcpy(vaddr, t.data, t.height * t.stride * bpp); 214382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } else { 215382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian GLubyte const * src = t.data + 216382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian (bounds.left + bounds.top * src_stride) * bpp; 217382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian GLubyte * dst = (GLubyte *)vaddr + 218382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian (bounds.left + bounds.top * dst_stride) * bpp; 219382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian const size_t length = bounds.width() * bpp; 220382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian size_t h = bounds.height(); 221382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian src_stride *= bpp; 222382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian dst_stride *= bpp; 223382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian while (h--) { 224382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian memcpy(dst, src, length); 225382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian dst += dst_stride; 226382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian src += src_stride; 227382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 228382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 229382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 230382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian buf->unlock(); 2311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 232382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian buffer->unlock(); 233382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 2341473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2359042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian } else 2369042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian#endif 2379042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian { 238382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian for (size_t i=0 ; i<NUM_BUFFERS ; i++) { 2396950e428feaccc8164b989ef64e771a99948797aMathias Agopian mTextures[i].image = EGL_NO_IMAGE_KHR; 240382e17d46fc54396a303593f2db3abe1fb911411Mathias Agopian } 2411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GGLSurface t; 2426950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 243dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian LOGE_IF(res, "error %d (%s) locking buffer %p", 244dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian res, strerror(res), buffer.get()); 245dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian if (res == NO_ERROR) { 2466950e428feaccc8164b989ef64e771a99948797aMathias Agopian loadTexture(&mTextures[0], dirty, t); 247dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian buffer->unlock(); 2481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2546950e428feaccc8164b989ef64e771a99948797aMathias Agopian int index = mFrontBufferIndex; 2556950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mTextures[index].image == EGL_NO_IMAGE_KHR) 2566950e428feaccc8164b989ef64e771a99948797aMathias Agopian index = 0; 2571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLuint textureName = mTextures[index].name; 2581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (UNLIKELY(textureName == -1LU)) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the texture has not been created yet, this Layer has 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in fact never been drawn into. this happens frequently with 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // SurfaceView. 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearWithOpenGL(clip); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 265999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian drawWithOpenGL(clip, mTextures[index]); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2686950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage) 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2706950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 271248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 272248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // this ensures our client doesn't go away while we're accessing 273248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the shared area. 274248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian sp<Client> ourClient(client.promote()); 275248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (ourClient == 0) { 276248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops, the client is already gone 277248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 278248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 279248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 2801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian /* 2819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * This is called from the client's Surface::dequeue(). This can happen 2829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * at any time, especially while we're in the middle of using the 2839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer 'index' as our front buffer. 2841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * 2859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * Make sure the buffer we're resizing is not the front buffer and has been 2869779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * dequeued. Once this condition is asserted, we are guaranteed that this 2879779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * buffer cannot become the front buffer under our feet, since we're called 2889779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian * from Surface::dequeue() 2891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 2909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->assertReallocate(index); 2919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); 292248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (err != NO_ERROR) { 293248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // the surface may have died 294248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian return buffer; 295248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 296248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 297248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian uint32_t w, h; 298248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian { // scope for the lock 299248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 300248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian w = mWidth; 301248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian h = mHeight; 302248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian buffer = mBuffers[index]; 303ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian 304ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian // destroy() could have been called before we get here, we log it 305ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian // because it's uncommon, and the code below should handle it 306ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian LOGW_IF(buffer==0, 307ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian "mBuffers[%d] is null (mWidth=%d, mHeight=%d)", 308ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian index, w, h); 309ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian 310248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mBuffers[index].clear(); 311248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 312248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian 3136950e428feaccc8164b989ef64e771a99948797aMathias Agopian const uint32_t effectiveUsage = getEffectiveUsage(usage); 314ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian if (buffer!=0 && buffer->getStrongCount() == 1) { 3156950e428feaccc8164b989ef64e771a99948797aMathias Agopian err = buffer->reallocate(w, h, mFormat, effectiveUsage); 3169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } else { 3179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // here we have to reallocate a new buffer because we could have a 3189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // client in our process with a reference to it (eg: status bar), 3199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // and we can't release the handle under its feet. 3209779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer.clear(); 3216950e428feaccc8164b989ef64e771a99948797aMathias Agopian buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); 3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian err = buffer->initCheck(); 3231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 3249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 3259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err || buffer->handle == 0) { 3269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err || buffer->handle == 0, 3279779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 3289779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, index, w, h, strerror(-err)); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3309779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGD_IF(DEBUG_RESIZE, 331e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 332e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, index, w, h, buffer->handle); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (err == NO_ERROR && buffer->handle != 0) { 336248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian Mutex::Autolock _l(mLock); 337248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian if (mWidth && mHeight) { 338248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // and we have new buffer 339248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mBuffers[index] = buffer; 340248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // texture is now dirty... 341248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian mTextures[index].dirty = true; 342248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } else { 343248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian // oops we got killed while we were allocating the buffer 344248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian buffer.clear(); 345248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian } 3466edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian } 3479779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian return buffer; 3486edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian} 3496edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian 3506950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 3516950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 3526950e428feaccc8164b989ef64e771a99948797aMathias Agopian /* 3536950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for software rendering, but h/w composition 3546950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 3556950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3566950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used for h/w rendering and h/w composition 3576950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with HW_RENDER | HW_TEXTURE 3586950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3596950e428feaccc8164b989ef64e771a99948797aMathias Agopian * buffers used with h/w rendering and either NPOT or no egl_image_ext 3606950e428feaccc8164b989ef64e771a99948797aMathias Agopian * are allocated with SW_READ_RARELY | HW_RENDER 3616950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 3626950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 3636950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3646950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (mSecure) { 3656950e428feaccc8164b989ef64e771a99948797aMathias Agopian // secure buffer, don't store it into the GPU 3666950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 3676950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBuffer::USAGE_SW_WRITE_OFTEN; 3686950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 3696950e428feaccc8164b989ef64e771a99948797aMathias Agopian // it's allowed to modify the usage flags here, but generally 3706950e428feaccc8164b989ef64e771a99948797aMathias Agopian // the requested flags should be honored. 371351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian if (mNoEGLImageForSwBuffers) { 372351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian if (usage & GraphicBuffer::USAGE_HW_MASK) { 373351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian // request EGLImage for h/w buffers only 374351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 375351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian } 376351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian } else { 377351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian // request EGLImage for all buffers 378351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 379351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian } 3806950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 3816950e428feaccc8164b989ef64e771a99948797aMathias Agopian return usage; 3826950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 3836950e428feaccc8164b989ef64e771a99948797aMathias Agopian 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& front(drawingState()); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& temp(currentState()); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian if ((front.requested_w != temp.requested_w) || 390e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian (front.requested_h != temp.requested_h)) { 3919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // the size changed, we need to ask our client to request a new buffer 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 3939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "resize (layer=%p), requested (%dx%d), " 3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "drawing (%d,%d), (%dx%d), (%dx%d)", 395e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian this, 396e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian int(temp.requested_w), int(temp.requested_h), 397e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian int(front.requested_w), int(front.requested_h), 3989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()), 3999779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight())); 4009779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 4019779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we're being resized and there is a freeze display request, 4029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // acquire a freeze lock, so that the screen stays put 4039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // until we've redrawn at the new size; this is to avoid 4049779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // glitches upon orientation changes. 4059779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (mFlinger->hasFreezeRequest()) { 4069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // if the surface is hidden, don't try to acquire the 4079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // freeze lock, since hidden surfaces may never redraw 4089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 4099779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFreezeLock = mFlinger->getFreezeLock(); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4127cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 413bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // this will make sure LayerBase::doTransaction doesn't update 414bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // the drawing state's size 415bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editDraw(mDrawingState); 416bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.requested_w = temp.requested_w; 417bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.requested_h = temp.requested_h; 418bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 41970cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian // record the new size, form this point on, when the client request a 42070cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian // buffer, it'll get the new size. 42170cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian setDrawingSize(temp.requested_w, temp.requested_h); 42270cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian 4237cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian // all buffers need reallocation 4247cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian lcblk->reallocate(); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.sequence != front.sequence) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeLock.clear(); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) { 4399779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian Mutex::Autolock _l(mLock); 4409779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mWidth = w; 4419779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mHeight = h; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling... 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4509779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian ssize_t buf = lcblk->retireAndLock(); 4519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (buf < NO_ERROR) { 4529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian //LOGW("nothing to retire (%s)", strerror(-buf)); 4539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // NOTE: here the buffer is locked because we will used 4549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // for composition later in the loop 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // we retired a buffer, which becomes the new front buffer 4599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mFrontBufferIndex = buf; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian // get the dirty region 4626950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 4639779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian const Region dirty(lcblk->getDirtyRegion(buf)); 4649779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4667cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian const Layer::State& front(drawingState()); 467bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian if (newFrontBuffer->getWidth() == front.requested_w && 468bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian newFrontBuffer->getHeight() == front.requested_h) 469bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 470bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian if ((front.w != front.requested_w) || 471bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian (front.h != front.requested_h)) 472bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian { 473bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // Here we pretend the transaction happened by updating the 474bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // current and drawing states. Drawing state is only accessed 475bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // in this thread, no need to have it locked 476bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editDraw(mDrawingState); 477bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.w = editDraw.requested_w; 478bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editDraw.h = editDraw.requested_h; 479bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 480bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // We also need to update the current state so that we don't 481bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // end-up doing too much work during the next transaction. 482bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // NOTE: We actually don't need hold the transaction lock here 483bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // because State::w and State::h are only accessed from 484bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // this thread 485bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian Layer::State& editTemp(currentState()); 486bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editTemp.w = editDraw.w; 487bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian editTemp.h = editDraw.h; 488bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian 489bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian // recompute visible region 490bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian recomputeVisibleRegions = true; 491bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian } 49246b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian 49346b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian // we now have the correct size, unfreeze the screen 49446b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian mFreezeLock.clear(); 4957cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian } 4967cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian 497e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian if (lcblk->getQueuedCount()) { 498e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian // signal an event if we have more buffers waiting 499e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian mFlinger->signalEvent(); 500e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5026950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (!mPostedDirtyRegion.isEmpty()) { 5036950e428feaccc8164b989ef64e771a99948797aMathias Agopian reloadTexture( mPostedDirtyRegion ); 5046950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip( 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirtyRegion.isEmpty()) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPostedDirtyRegion.clear(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The dirty region is given in the layer's coordinate space 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transform the dirty region by the surface's transformation 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the global transformation. 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Layer::State& s(drawingState()); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Transform tr(planeTransform * s.transform); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point, the dirty region is in screen space. 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure it's constrained by the visible region (which 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is in screen space as well). 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5265469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian if (visibleRegionScreen.isEmpty()) { 5275469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian // an invisible layer should not hold a freeze-lock 5285469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian // (because it may never be updated and thereore never release it) 5295469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian mFreezeLock.clear(); 5305469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip() 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian status_t err = lcblk->unlock( mFrontBufferIndex ); 5369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(err!=NO_ERROR, 5379779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "layer %p, buffer=%d wasn't locked!", 5389779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian this, mFrontBufferIndex); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// --------------------------------------------------------------------------- 5421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 5436cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 5446cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian SurfaceID id, const sp<Layer>& owner) 5456cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian : Surface(flinger, id, owner->getIdentity(), owner) 5466cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{ 5476cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian} 5486cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian 5496cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer() 5501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 5511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 5521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 5536950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 5541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 5556950e428feaccc8164b989ef64e771a99948797aMathias Agopian sp<GraphicBuffer> buffer; 5561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian sp<Layer> owner(getOwner()); 5571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (owner != 0) { 5589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian LOGE_IF(uint32_t(index)>=NUM_BUFFERS, 5599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian "getBuffer() index (%d) out of range", index); 5609779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian if (uint32_t(index) < NUM_BUFFERS) { 5619779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian buffer = owner->requestBuffer(index, usage); 5629779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian } 5631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 5641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return buffer; 5651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 571