Layer.cpp revision 9779b221e999583ff89e0dfc40e56398737adbb3
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
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/PixelFormat.h>
291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <ui/Surface.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#include "Buffer.h"
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)
529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    :   LayerBaseClient(flinger, display, c, i), lcblk(NULL),
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSecure(false),
549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        mNeedsBlending(true)
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // no OpenGL operation is possible here, since we might not be
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // in the OpenGL thread.
589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS);
599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFrontBufferIndex = lcblk->getFrontBuffer();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer()
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
64a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian    destroy();
65a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian    // the actual buffers will be destroyed here
669779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    delete lcblk;
679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
68a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian}
69a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian
70a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopianvoid Layer::destroy()
71a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian{
729779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (mTextures[i].name != -1U) {
7481b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian            glDeleteTextures(1, &mTextures[i].name);
75a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian            mTextures[i].name = -1U;
761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            eglDestroyImageKHR(dpy, mTextures[i].image);
80a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        mBuffers[i].clear();
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
84359140c171f67b9b29a1beae9743b49d0759414bMathias Agopian    mSurface.clear();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mSurface;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
926cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopianstatus_t Layer::ditch()
936cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{
94a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
95a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian    destroy();
966cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian    return NO_ERROR;
976cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian}
986cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian
996edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            PixelFormat format, uint32_t flags)
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PixelFormatInfo info;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err) return err;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    uint32_t bufferFlags = 0;
1071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (flags & ISurfaceComposer::eSecure)
1081473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        bufferFlags |= Buffer::SECURE;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFormat = format;
1119779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mWidth = w;
1129779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
1131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
1159779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mBufferFlags = bufferFlags;
1169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
1179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        mBuffers[i] = new Buffer();
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1196cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
1269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    sp<Buffer> buffer(getFrontBuffer());
127dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian    if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
1281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        int index = mFrontBufferIndex;
1291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (LIKELY(!mTextures[index].dirty)) {
1301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
1311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        } else {
1321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // we need to recreate the texture
1331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
1341473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // create the new texture name if needed
1361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (UNLIKELY(mTextures[index].name == -1U)) {
1371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[index].name = createTexture();
1381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            } else {
1391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
1401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // free the previous image
1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
1441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                eglDestroyImageKHR(dpy, mTextures[index].image);
1451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[index].image = EGL_NO_IMAGE_KHR;
1461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // construct an EGL_NATIVE_BUFFER_ANDROID
1491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
1501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // create the new EGLImageKHR
1521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            const EGLint attrs[] = {
1531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
1541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    EGL_NONE,                   EGL_NONE
1551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            };
1561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            mTextures[index].image = eglCreateImageKHR(
1571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
1581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    (EGLClientBuffer)clientBuf, attrs);
1591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR,
1611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    "eglCreateImageKHR() failed. err=0x%4x",
1621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    eglGetError());
1631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
1651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
1661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                        (GLeglImageOES)mTextures[index].image);
1671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                GLint error = glGetError();
1681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                if (UNLIKELY(error != GL_NO_ERROR)) {
1691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // this failed, for instance, because we don't support
1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // NPOT.
1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // FIXME: do something!
1721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
1731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                } else {
1741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // Everything went okay!
175999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].dirty  = false;
176999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].width  = clientBuf->width;
177999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].height = clientBuf->height;
1781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                }
1791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
1811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    } else {
1821473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        GGLSurface t;
183dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY);
184dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
185dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian                res, strerror(res), buffer.get());
186dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian        if (res == NO_ERROR) {
1871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (UNLIKELY(mTextures[0].name == -1U)) {
1881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[0].name = createTexture();
1891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
190999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian            loadTexture(&mTextures[0], mTextures[0].name, dirty, t);
191dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian            buffer->unlock();
1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ?
2001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            mFrontBufferIndex : 0;
2011473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    GLuint textureName = mTextures[index].name;
2021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (UNLIKELY(textureName == -1LU)) {
2039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        //LOGW("Layer %p doesn't have a texture", this);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the texture has not been created yet, this Layer has
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // in fact never been drawn into. this happens frequently with
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // SurfaceView.
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clearWithOpenGL(clip);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
211999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian    drawWithOpenGL(clip, mTextures[index]);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopiansp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    /*
2179779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
2189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * at any time, especially while we're in the middle of using the
2199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * buffer 'index' as our front buffer.
2201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian     *
2219779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
2229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
2239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
2249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * from Surface::dequeue()
2251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian     */
2269779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    status_t err = lcblk->assertReallocate(index);
2279779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
2281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
2299779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
2309779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    uint32_t w = mWidth;
2319779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    uint32_t h = mHeight;
2321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
2339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    sp<Buffer>& buffer(mBuffers[index]);
2349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (buffer->getStrongCount() == 1) {
2359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
2369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    } else {
2379779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // here we have to reallocate a new buffer because we could have a
2389779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // client in our process with a reference to it (eg: status bar),
2399779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // and we can't release the handle under its feet.
2409779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        buffer.clear();
2419779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        buffer = new Buffer(w, h, mFormat, usage, mBufferFlags);
2429779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        err = buffer->initCheck();
2431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    }
2449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err || buffer->handle == 0) {
2469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE_IF(err || buffer->handle == 0,
2479779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
2489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                this, index, w, h, strerror(-err));
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2509779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGD_IF(DEBUG_RESIZE,
2519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d",
2529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                this, index, w, h);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
2569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // texture is now dirty...
2579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        mTextures[index].dirty = true;
2586edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian    }
2599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    return buffer;
2606edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian}
2616edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& front(drawingState());
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& temp(currentState());
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Index of the back buffer
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (backbufferChanged) {
2719779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // the size changed, we need to ask our client to request a new buffer
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
2739779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    "resize (layer=%p), requested (%dx%d), "
2749779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    "drawing (%d,%d), (%dx%d), (%dx%d)",
2759779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    this, int(temp.w), int(temp.h),
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int(drawingState().w), int(drawingState().h),
2779779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
2789779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
2799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // record the new size, form this point on, when the client request a
2819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // buffer, it'll get the new size.
2829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        setDrawingSize(temp.w, temp.h);
2839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2849779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // all buffers need reallocation
2859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        lcblk->reallocate();
2869779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2879779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // recompute the visible region
2889779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // FIXME: ideally we would do that only when we have received
2899779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // a buffer of the right size
2909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        flags |= Layer::eVisibleRegion;
2919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        this->contentDirty = true;
2929779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#if 0
2949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // FIXME: handle freeze lock
2959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // we're being resized and there is a freeze display request,
2969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // acquire a freeze lock, so that the screen stays put
2979779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // until we've redrawn at the new size; this is to avoid
2989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // glitches upon orientation changes.
2999779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        if (mFlinger->hasFreezeRequest()) {
3009779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            // if the surface is hidden, don't try to acquire the
3019779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            // freeze lock, since hidden surfaces may never redraw
3029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
3039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                mFreezeLock = mFlinger->getFreezeLock();
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian#endif
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (temp.sequence != front.sequence) {
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFreezeLock.clear();
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return LayerBase::doTransaction(flags);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) {
3219779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mWidth = w;
3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling...
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    ssize_t buf = lcblk->retireAndLock();
3339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (buf < NO_ERROR) {
3349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        //LOGW("nothing to retire (%s)", strerror(-buf));
3359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // NOTE: here the buffer is locked because we will used
3369779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // for composition later in the loop
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
3409779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // we retired a buffer, which becomes the new front buffer
3419779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFrontBufferIndex = buf;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3439779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // get the dirty region
3449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    sp<Buffer> newFrontBuffer(getBuffer(buf));
3459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    const Region dirty(lcblk->getDirtyRegion(buf));
3469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // FIXME: signal an event if we have more buffers waiting
3499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // mFlinger->signalEvent();
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    reloadTexture( mPostedDirtyRegion );
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip(
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPostedDirtyRegion.clear();
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The dirty region is given in the layer's coordinate space
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // transform the dirty region by the surface's transformation
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // and the global transformation.
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Layer::State& s(drawingState());
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform tr(planeTransform * s.transform);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // At this point, the dirty region is in screen space.
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make sure it's constrained by the visible region (which
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // is in screen space as well).
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip()
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3779779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    status_t err = lcblk->unlock( mFrontBufferIndex );
3789779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    LOGE_IF(err!=NO_ERROR,
3799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            "layer %p, buffer=%d wasn't locked!",
3809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            this, mFrontBufferIndex);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// ---------------------------------------------------------------------------
3841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
3856cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
3866cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian        SurfaceID id, const sp<Layer>& owner)
3876cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian    : Surface(flinger, id, owner->getIdentity(), owner)
3886cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{
3896cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian}
3906cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian
3916cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
3921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
3931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
3941473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopiansp<SurfaceBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
3961473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
3979779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    sp<SurfaceBuffer> buffer;
3981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    sp<Layer> owner(getOwner());
3991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (owner != 0) {
4009779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
4019779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "getBuffer() index (%d) out of range", index);
4029779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        if (uint32_t(index) < NUM_BUFFERS) {
4039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            buffer = owner->requestBuffer(index, usage);
4049779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        }
4051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    }
4061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    return buffer;
4071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
413