Layer.cpp revision 1b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
309cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
319cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopiantemplate <typename T> inline T min(T a, T b) {
45ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    return a<b ? a : b;
46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian}
47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display,
51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        const sp<Client>& c, int32_t i)
5248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    :   LayerBaseClient(flinger, display, c, i),
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecure(false),
54a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        mNoEGLImageForSwBuffers(false),
55401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsBlending(true),
56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsDithering(false)
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // no OpenGL operation is possible here, since we might not be
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // in the OpenGL thread.
60cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFrontBufferIndex = lcblk->getFrontBuffer();
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    destroy();
660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the actual buffers will be destroyed here
6748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
68cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopianvoid Layer::destroy()
700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian{
71cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (mTextures[i].name != -1U) {
73550b79f4491909b0f223d8fb25155974f53b3f79Mathias Agopian            glDeleteTextures(1, &mTextures[i].name);
740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            mTextures[i].name = -1U;
75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            eglDestroyImageKHR(dpy, mTextures[i].image);
790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
8148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
82cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mBuffers[i].clear();
8348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        mWidth = mHeight = 0;
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
858c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    mSurface.clear();
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSurface;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
96f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
978c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    destroy();
989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
101f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
104401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
109401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
110401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
111ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
112ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
113ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
114ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
115ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
116ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
117ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
118ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
119ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
120401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
121401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
122a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
123a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
124cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
125ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
126cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
1273330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
129a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
130ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
131401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
132401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
133401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
134401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
135401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
136cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
1373330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBuffers[i] = new GraphicBuffer();
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
145cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
1469ec430adaea1cb88eaa1e78c7f759cd42ab6cf7aMathias Agopian    sp<GraphicBuffer> buffer(getFrontBufferLocked());
1478f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
1488f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
1498f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
1508f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
1518f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
1528f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
1538f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
1548f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    const int index = mFrontBufferIndex;
15557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
15657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    // create the new texture name if needed
15757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (UNLIKELY(mTextures[index].name == -1U)) {
15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].name = createTexture();
15957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].width = 0;
16057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].height = 0;
16157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    }
16257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
16354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer
16457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
16557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
16657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (mTextures[index].dirty) {
167fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) {
168fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    // not sure what we can do here...
169fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
170fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    goto slowpath;
171fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                }
17257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            }
173076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        } else {
17457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
17557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    mHybridBuffer->height != buffer->height)) {
17657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                mHybridBuffer.clear();
17757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                mHybridBuffer = new GraphicBuffer(
17857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        buffer->width, buffer->height, buffer->format,
17957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        GraphicBuffer::USAGE_SW_WRITE_OFTEN |
18057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        GraphicBuffer::USAGE_HW_TEXTURE);
181fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                if (initializeEglImage(
182fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                        mHybridBuffer, &mTextures[0]) != NO_ERROR) {
183fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    // not sure what we can do here...
184fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
185fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mHybridBuffer.clear();
186fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    goto slowpath;
187fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                }
188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
189076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
19057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            GGLSurface t;
19157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
19257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
19357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    res, strerror(res), buffer.get());
19457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (res == NO_ERROR) {
19557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                Texture* const texture(&mTextures[0]);
19657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
19757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                glBindTexture(GL_TEXTURE_2D, texture->name);
19857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
19957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                sp<GraphicBuffer> buf(mHybridBuffer);
20057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                void* vaddr;
20157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr);
20257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                if (res == NO_ERROR) {
20357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    int bpp = 0;
20457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    switch (t.format) {
20554ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGB_565:
20654ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBA_4444:
20757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        bpp = 2;
20857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        break;
20954ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBA_8888:
21054ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBX_8888:
21157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        bpp = 4;
21257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        break;
21357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    default:
21454ed4f6282bdea251455f39b978626026affdbefMathias Agopian                        if (isSupportedYuvFormat(t.format)) {
21554ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            // just show the Y plane of YUV buffers
21654ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            bpp = 1;
21754ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            break;
21854ed4f6282bdea251455f39b978626026affdbefMathias Agopian                        }
21957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        // oops, we don't handle this format!
22057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        LOGE("layer %p, texture=%d, using format %d, which is not "
22157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                "supported by the GL", this, texture->name, t.format);
22257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    }
22357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    if (bpp) {
22457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        const Rect bounds(dirty.getBounds());
22557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        size_t src_stride = t.stride;
22657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        size_t dst_stride = buf->stride;
22757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        if (src_stride == dst_stride &&
22857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            bounds.width() == t.width &&
22957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            bounds.height() == t.height)
23057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        {
23157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            memcpy(vaddr, t.data, t.height * t.stride * bpp);
23257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        } else {
23357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            GLubyte const * src = t.data +
23457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                (bounds.left + bounds.top * src_stride) * bpp;
23557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            GLubyte * dst = (GLubyte *)vaddr +
23657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                (bounds.left + bounds.top * dst_stride) * bpp;
23757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            const size_t length = bounds.width() * bpp;
23857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            size_t h = bounds.height();
23957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            src_stride *= bpp;
24057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            dst_stride *= bpp;
24157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            while (h--) {
24257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                memcpy(dst, src, length);
24357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                dst += dst_stride;
24457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                src += src_stride;
24557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            }
24657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        }
24757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    }
24857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    buf->unlock();
249076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
25057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                buffer->unlock();
25157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            }
252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
25354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    } else
25454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif
25554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    {
256fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
25757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
2583330b203039dea366d4981db1408a460134b2d2cMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
25957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        }
260076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
2613330b203039dea366d4981db1408a460134b2d2cMathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
2620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
2630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                res, strerror(res), buffer.get());
2640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (res == NO_ERROR) {
2653330b203039dea366d4981db1408a460134b2d2cMathias Agopian            loadTexture(&mTextures[0], dirty, t);
2660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            buffer->unlock();
267076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2733330b203039dea366d4981db1408a460134b2d2cMathias Agopian    int index = mFrontBufferIndex;
2743330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mTextures[index].image == EGL_NO_IMAGE_KHR)
2753330b203039dea366d4981db1408a460134b2d2cMathias Agopian        index = 0;
276076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    GLuint textureName = mTextures[index].name;
277076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (UNLIKELY(textureName == -1LU)) {
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // in fact never been drawn into. this happens frequently with
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // SurfaceView.
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        clearWithOpenGL(clip);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2841fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian    drawWithOpenGL(clip, mTextures[index]);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2873330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2893330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
29148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
29248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
29348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    sp<Client> ourClient(client.promote());
29448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (ourClient == 0) {
29548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
29648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
29748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
29848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
299076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
300cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
301cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
303076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     *
304cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
307cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * from Surface::dequeue()
308076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
309cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->assertReallocate(index);
310cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
31148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (err != NO_ERROR) {
31248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // the surface may have died
31348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
31448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
31548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
31648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    uint32_t w, h;
31748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
31848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
31948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        w = mWidth;
32048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        h = mHeight;
32148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        buffer = mBuffers[index];
3226d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian
3236d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        // destroy() could have been called before we get here, we log it
3246d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        // because it's uncommon, and the code below should handle it
3256d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        LOGW_IF(buffer==0,
3266d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian                "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
3276d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian                index, w, h);
3286d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian
32948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        mBuffers[index].clear();
33048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
33148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
3336d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian    if (buffer!=0 && buffer->getStrongCount() == 1) {
3343330b203039dea366d4981db1408a460134b2d2cMathias Agopian        err = buffer->reallocate(w, h, mFormat, effectiveUsage);
335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
336cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // here we have to reallocate a new buffer because we could have a
337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // client in our process with a reference to it (eg: status bar),
338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // and we can't release the handle under its feet.
339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        buffer.clear();
3403330b203039dea366d4981db1408a460134b2d2cMathias Agopian        buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage);
341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = buffer->initCheck();
342076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
343cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
344cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
345cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
346cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
347cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
349cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
3507e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
3517e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
354cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
35548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
35648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (mWidth && mHeight) {
35748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // and we have new buffer
35848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mBuffers[index] = buffer;
35948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // texture is now dirty...
36048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mTextures[index].dirty = true;
36148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        } else {
36248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // oops we got killed while we were allocating the buffer
36348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            buffer.clear();
36448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
365f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
366cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
367f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
368f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
3693330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
3703330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
3713330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
3723330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
3733330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
3743330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3753330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
3763330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
3773330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3783330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
3793330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3813330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
3823330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3833330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
3843330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
3853330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
3863330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
3873330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
3883330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
3893330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
390a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        if (mNoEGLImageForSwBuffers) {
391a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            if (usage & GraphicBuffer::USAGE_HW_MASK) {
392a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian                // request EGLImage for h/w buffers only
393a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian                usage |= GraphicBuffer::USAGE_HW_TEXTURE;
394a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            }
395a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        } else {
396a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            // request EGLImage for all buffers
397a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
398a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        }
3993330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
4003330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
4013330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
4023330b203039dea366d4981db1408a460134b2d2cMathias Agopian
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    if ((front.requested_w != temp.requested_w) ||
4097e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        (front.requested_h != temp.requested_h)) {
410cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    "resize (layer=%p), requested (%dx%d), "
413cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    "drawing (%d,%d), (%dx%d), (%dx%d)",
4147e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    this,
4157e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    int(temp.requested_w), int(temp.requested_h),
4167e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    int(front.requested_w), int(front.requested_h),
417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
420cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // we're being resized and there is a freeze display request,
421cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // acquire a freeze lock, so that the screen stays put
422cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // until we've redrawn at the new size; this is to avoid
423cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // glitches upon orientation changes.
424cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (mFlinger->hasFreezeRequest()) {
425cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            // if the surface is hidden, don't try to acquire the
426cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            // freeze lock, since hidden surfaces may never redraw
427cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
428cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mFreezeLock = mFlinger->getFreezeLock();
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
431caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
432df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        // this will make sure LayerBase::doTransaction doesn't update
433df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        // the drawing state's size
434df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        Layer::State& editDraw(mDrawingState);
435df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        editDraw.requested_w = temp.requested_w;
436df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        editDraw.requested_h = temp.requested_h;
437df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
4386656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        // record the new size, form this point on, when the client request a
4396656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        // buffer, it'll get the new size.
4406656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        setDrawingSize(temp.requested_w, temp.requested_h);
4416656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
442caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian        // all buffers need reallocation
443caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian        lcblk->reallocate();
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
457cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) {
458cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
459cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
460cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
469cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
470cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (buf < NO_ERROR) {
471cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        //LOGW("nothing to retire (%s)", strerror(-buf));
472cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // NOTE: here the buffer is locked because we will used
473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    // ouch, this really should never happen
478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (uint32_t(buf)>=NUM_BUFFERS) {
479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
484cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
485cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFrontBufferIndex = buf;
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
487cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // get the dirty region
4883330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
498df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
507d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
513d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
517d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
518d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
519d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
520d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
5218f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
522d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
523d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
524d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
525d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
526d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
527d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
528d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
529d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
530d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
531caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
532caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
533e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
534e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
535e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
536e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
538245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
539245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
540245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
541245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
542245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
543245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
544245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
545245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
546245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
568c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
569c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
5701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
571c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
572c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip()
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
577cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->unlock( mFrontBufferIndex );
578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err!=NO_ERROR,
579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "layer %p, buffer=%d wasn't locked!",
580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            this, mFrontBufferIndex);
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
5851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
5861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
5871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    SharedBufferStack::Statistics stats = lcblk->getStats();
5891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append( lcblk->dump("      ") );
5901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
5911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
5921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
5931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
5941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
5951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
5961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
5971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
5981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
5991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
6001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
6011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
6021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
6031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
6041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
6051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
6061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
6071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
6081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            pixelFormat(),
6091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            w0, h0, s0, w1, h1, s1,
6101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            getFreezeLock().get(), stats.totalTime);
6111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
6121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
6131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
6141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
6179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
6189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        SurfaceID id, const sp<Layer>& owner)
6199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    : Surface(flinger, id, owner->getIdentity(), owner)
6209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
6219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
6229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
6239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
6273330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
6293330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
631076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "getBuffer() index (%d) out of range", index);
634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (uint32_t(index) < NUM_BUFFERS) {
635cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            buffer = owner->requestBuffer(index, usage);
636cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
645