Layer.cpp revision d343e3d5e3177806205b9452b0b43907e28afd9a
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
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const Layer::typeID = "Layer";
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display,
52cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        const sp<Client>& c, int32_t i)
5348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    :   LayerBaseClient(flinger, display, c, i),
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecure(false),
55a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        mNoEGLImageForSwBuffers(false),
56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsBlending(true),
57401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsDithering(false)
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // no OpenGL operation is possible here, since we might not be
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // in the OpenGL thread.
61cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFrontBufferIndex = lcblk->getFrontBuffer();
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    destroy();
670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the actual buffers will be destroyed here
6848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
69cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopianvoid Layer::destroy()
710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian{
72cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (mTextures[i].name != -1U) {
74550b79f4491909b0f223d8fb25155974f53b3f79Mathias Agopian            glDeleteTextures(1, &mTextures[i].name);
750aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            mTextures[i].name = -1U;
76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            eglDestroyImageKHR(dpy, mTextures[i].image);
800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
8248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
83cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mBuffers[i].clear();
8448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        mWidth = mHeight = 0;
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    mSurface.clear();
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSurface;
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
97f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
988c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    destroy();
999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
102f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
105401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
111401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
112401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
113401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
114a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
115a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
116cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
117cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
118cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
1193330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
121a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
122a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
123401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
124401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
125401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
126401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
127401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
128cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
1293330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBuffers[i] = new GraphicBuffer();
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
1389ec430adaea1cb88eaa1e78c7f759cd42ab6cf7aMathias Agopian    sp<GraphicBuffer> buffer(getFrontBufferLocked());
1398f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
1408f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
1418f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
1428f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
1438f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
1448f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
1458f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
1468f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    const int index = mFrontBufferIndex;
14757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
14857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    // create the new texture name if needed
14957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (UNLIKELY(mTextures[index].name == -1U)) {
15057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].name = createTexture();
15157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].width = 0;
15257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        mTextures[index].height = 0;
15357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    }
15457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
15554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer
15657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
15757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (mTextures[index].dirty) {
159fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) {
160fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    // not sure what we can do here...
161fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
162fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    goto slowpath;
163fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                }
16457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            }
165076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        } else {
16657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
16757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    mHybridBuffer->height != buffer->height)) {
16857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                mHybridBuffer.clear();
16957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                mHybridBuffer = new GraphicBuffer(
17057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        buffer->width, buffer->height, buffer->format,
17157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        GraphicBuffer::USAGE_SW_WRITE_OFTEN |
17257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        GraphicBuffer::USAGE_HW_TEXTURE);
173fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                if (initializeEglImage(
174fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                        mHybridBuffer, &mTextures[0]) != NO_ERROR) {
175fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    // not sure what we can do here...
176fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
177fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    mHybridBuffer.clear();
178fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                    goto slowpath;
179fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                }
180076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
18257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            GGLSurface t;
18357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
18457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
18557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    res, strerror(res), buffer.get());
18657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            if (res == NO_ERROR) {
18757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                Texture* const texture(&mTextures[0]);
18857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
18957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                glBindTexture(GL_TEXTURE_2D, texture->name);
19057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
19157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                sp<GraphicBuffer> buf(mHybridBuffer);
19257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                void* vaddr;
19357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr);
19457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                if (res == NO_ERROR) {
19557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    int bpp = 0;
19657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    switch (t.format) {
19754ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGB_565:
19854ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBA_4444:
19957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        bpp = 2;
20057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        break;
20154ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBA_8888:
20254ed4f6282bdea251455f39b978626026affdbefMathias Agopian                    case HAL_PIXEL_FORMAT_RGBX_8888:
20357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        bpp = 4;
20457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        break;
20557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    default:
20654ed4f6282bdea251455f39b978626026affdbefMathias Agopian                        if (isSupportedYuvFormat(t.format)) {
20754ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            // just show the Y plane of YUV buffers
20854ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            bpp = 1;
20954ed4f6282bdea251455f39b978626026affdbefMathias Agopian                            break;
21054ed4f6282bdea251455f39b978626026affdbefMathias Agopian                        }
21157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        // oops, we don't handle this format!
21257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        LOGE("layer %p, texture=%d, using format %d, which is not "
21357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                "supported by the GL", this, texture->name, t.format);
21457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    }
21557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    if (bpp) {
21657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        const Rect bounds(dirty.getBounds());
21757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        size_t src_stride = t.stride;
21857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        size_t dst_stride = buf->stride;
21957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        if (src_stride == dst_stride &&
22057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            bounds.width() == t.width &&
22157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            bounds.height() == t.height)
22257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        {
22357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            memcpy(vaddr, t.data, t.height * t.stride * bpp);
22457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        } else {
22557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            GLubyte const * src = t.data +
22657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                (bounds.left + bounds.top * src_stride) * bpp;
22757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            GLubyte * dst = (GLubyte *)vaddr +
22857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                (bounds.left + bounds.top * dst_stride) * bpp;
22957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            const size_t length = bounds.width() * bpp;
23057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            size_t h = bounds.height();
23157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            src_stride *= bpp;
23257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            dst_stride *= bpp;
23357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            while (h--) {
23457720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                memcpy(dst, src, length);
23557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                dst += dst_stride;
23657720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                                src += src_stride;
23757720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                            }
23857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                        }
23957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    }
24057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                    buf->unlock();
241076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
24257720c384af81327d327ef8b88078f11a750fd05Mathias Agopian                buffer->unlock();
24357720c384af81327d327ef8b88078f11a750fd05Mathias Agopian            }
244076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
24554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    } else
24654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif
24754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    {
248fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
24957720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
2503330b203039dea366d4981db1408a460134b2d2cMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
25157720c384af81327d327ef8b88078f11a750fd05Mathias Agopian        }
252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
2533330b203039dea366d4981db1408a460134b2d2cMathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
2540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
2550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                res, strerror(res), buffer.get());
2560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (res == NO_ERROR) {
2573330b203039dea366d4981db1408a460134b2d2cMathias Agopian            loadTexture(&mTextures[0], dirty, t);
2580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            buffer->unlock();
259076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2653330b203039dea366d4981db1408a460134b2d2cMathias Agopian    int index = mFrontBufferIndex;
2663330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mTextures[index].image == EGL_NO_IMAGE_KHR)
2673330b203039dea366d4981db1408a460134b2d2cMathias Agopian        index = 0;
268076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    GLuint textureName = mTextures[index].name;
269076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (UNLIKELY(textureName == -1LU)) {
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // in fact never been drawn into. this happens frequently with
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // SurfaceView.
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        clearWithOpenGL(clip);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2761fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian    drawWithOpenGL(clip, mTextures[index]);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2793330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2813330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
28248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
28348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
28448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
28548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    sp<Client> ourClient(client.promote());
28648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (ourClient == 0) {
28748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
28848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
28948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
292cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
293cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
294cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
295076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     *
296cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
297cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
298cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
299cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * from Surface::dequeue()
300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
301cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->assertReallocate(index);
302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
30348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (err != NO_ERROR) {
30448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // the surface may have died
30548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
30648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
30748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
30848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    uint32_t w, h;
30948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
31048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
31148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        w = mWidth;
31248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        h = mHeight;
31348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        buffer = mBuffers[index];
3146d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian
3156d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        // destroy() could have been called before we get here, we log it
3166d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        // because it's uncommon, and the code below should handle it
3176d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian        LOGW_IF(buffer==0,
3186d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian                "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
3196d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian                index, w, h);
3206d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian
32148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        mBuffers[index].clear();
32248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
32348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
3243330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
3256d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian    if (buffer!=0 && buffer->getStrongCount() == 1) {
3263330b203039dea366d4981db1408a460134b2d2cMathias Agopian        err = buffer->reallocate(w, h, mFormat, effectiveUsage);
327cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // here we have to reallocate a new buffer because we could have a
329cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // client in our process with a reference to it (eg: status bar),
330cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // and we can't release the handle under its feet.
331cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        buffer.clear();
3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian        buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage);
333cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = buffer->initCheck();
334076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
336cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
3427e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
3437e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
34748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
34848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (mWidth && mHeight) {
34948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // and we have new buffer
35048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mBuffers[index] = buffer;
35148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // texture is now dirty...
35248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mTextures[index].dirty = true;
35348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        } else {
35448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            // oops we got killed while we were allocating the buffer
35548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            buffer.clear();
35648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
357f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
358cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
359f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
360f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
3613330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
3623330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
3663330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3673330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
3683330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
3693330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3703330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
3713330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
3723330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3733330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
3743330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3753330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
3763330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
3773330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
3783330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
3793330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
3813330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
382a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        if (mNoEGLImageForSwBuffers) {
383a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            if (usage & GraphicBuffer::USAGE_HW_MASK) {
384a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian                // request EGLImage for h/w buffers only
385a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian                usage |= GraphicBuffer::USAGE_HW_TEXTURE;
386a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            }
387a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        } else {
388a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            // request EGLImage for all buffers
389a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
390a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian        }
3913330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
3923330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
3933330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
3943330b203039dea366d4981db1408a460134b2d2cMathias Agopian
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4007e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    if ((front.requested_w != temp.requested_w) ||
4017e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        (front.requested_h != temp.requested_h)) {
402cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
404cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    "resize (layer=%p), requested (%dx%d), "
405cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    "drawing (%d,%d), (%dx%d), (%dx%d)",
4067e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    this,
4077e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    int(temp.requested_w), int(temp.requested_h),
4087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                    int(front.requested_w), int(front.requested_h),
409cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
410cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
411cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // we're being resized and there is a freeze display request,
413cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // acquire a freeze lock, so that the screen stays put
414cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // until we've redrawn at the new size; this is to avoid
415cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // glitches upon orientation changes.
416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (mFlinger->hasFreezeRequest()) {
417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            // if the surface is hidden, don't try to acquire the
418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            // freeze lock, since hidden surfaces may never redraw
419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
420cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mFreezeLock = mFlinger->getFreezeLock();
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
423caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
424df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        // this will make sure LayerBase::doTransaction doesn't update
425df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        // the drawing state's size
426df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        Layer::State& editDraw(mDrawingState);
427df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        editDraw.requested_w = temp.requested_w;
428df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        editDraw.requested_h = temp.requested_h;
429df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
4306656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        // record the new size, form this point on, when the client request a
4316656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        // buffer, it'll get the new size.
4326656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        setDrawingSize(temp.requested_w, temp.requested_h);
4336656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
434caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian        // all buffers need reallocation
435caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian        lcblk->reallocate();
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
437cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
449cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) {
450cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
451cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
461cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
462cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (buf < NO_ERROR) {
463cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        //LOGW("nothing to retire (%s)", strerror(-buf));
464cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // NOTE: here the buffer is locked because we will used
465cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
468d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
469d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    // ouch, this really should never happen
470d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (uint32_t(buf)>=NUM_BUFFERS) {
471d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
472d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
473d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
474d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
476cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
477cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFrontBufferIndex = buf;
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
479cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // get the dirty region
4803330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
484d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
485d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
490df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
498d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
507d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
5138f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
517d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
518d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
519d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
520d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
521d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
522d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
523caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
524caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
525e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
526e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
527e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
528e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5303330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (!mPostedDirtyRegion.isEmpty()) {
5313330b203039dea366d4981db1408a460134b2d2cMathias Agopian        reloadTexture( mPostedDirtyRegion );
5323330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
554c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
555c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
556c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // (because it may never be updated and thereore never release it)
557c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
558c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip()
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
563cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->unlock( mFrontBufferIndex );
564cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err!=NO_ERROR,
565cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "layer %p, buffer=%d wasn't locked!",
566cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            this, mFrontBufferIndex);
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
5729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        SurfaceID id, const sp<Layer>& owner)
5739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    : Surface(flinger, id, owner->getIdentity(), owner)
5749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
5759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
5769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
5779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5813330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
5833330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
586cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
587cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "getBuffer() index (%d) out of range", index);
588cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (uint32_t(index) < NUM_BUFFERS) {
589cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            buffer = owner->requestBuffer(index, usage);
590cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
599