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