Layer.cpp revision 6950e428feaccc8164b989ef64e771a99948797a
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),
54cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian        mNeedsBlending(true),
55cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian        mNeedsDithering(false)
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // no OpenGL operation is possible here, since we might not be
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // in the OpenGL thread.
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
66248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian}
679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
68a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopianvoid Layer::destroy()
69a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian{
709779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (mTextures[i].name != -1U) {
7281b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian            glDeleteTextures(1, &mTextures[i].name);
73a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian            mTextures[i].name = -1U;
741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            eglDestroyImageKHR(dpy, mTextures[i].image);
78a3aa6c9aa96873a70e2ff3170218a275f503520eMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
80248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        Mutex::Autolock _l(mLock);
819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        mBuffers[i].clear();
82248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        mWidth = mHeight = 0;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
842e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias 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
952e4b68d57bb64d7e93139238c5a8be91ff956c2aMathias 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{
102cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // this surfaces pixel format
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PixelFormatInfo info;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err) return err;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
107cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // the display's pixel format
108cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
109cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    PixelFormatInfo displayInfo;
110cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
111cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian
1129779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFormat = format;
1139779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mWidth = w;
1149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
1156950e428feaccc8164b989ef64e771a99948797aMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
117cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian
118cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // we use the red index
119cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
120cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
121cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
122cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian
1239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
1246950e428feaccc8164b989ef64e771a99948797aMathias Agopian        mBuffers[i] = new GraphicBuffer();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1266cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1329779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
1336950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> buffer(getFrontBuffer());
1346950e428feaccc8164b989ef64e771a99948797aMathias Agopian    if (LIKELY((mFlags & DisplayHardware::DIRECT_TEXTURE) &&
1356950e428feaccc8164b989ef64e771a99948797aMathias Agopian            (buffer->usage & GRALLOC_USAGE_HW_TEXTURE))) {
1361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        int index = mFrontBufferIndex;
1371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        if (LIKELY(!mTextures[index].dirty)) {
1381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
1391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        } else {
1401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // we need to recreate the texture
1411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
1421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // create the new texture name if needed
1441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (UNLIKELY(mTextures[index].name == -1U)) {
1451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[index].name = createTexture();
1461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            } else {
1471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
1481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // free the previous image
1511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
1521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                eglDestroyImageKHR(dpy, mTextures[index].image);
1531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[index].image = EGL_NO_IMAGE_KHR;
1541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // construct an EGL_NATIVE_BUFFER_ANDROID
1571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
1581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            // create the new EGLImageKHR
1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            const EGLint attrs[] = {
1611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
1621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    EGL_NONE,                   EGL_NONE
1631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            };
1641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            mTextures[index].image = eglCreateImageKHR(
1651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
1661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    (EGLClientBuffer)clientBuf, attrs);
1671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR,
1691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    "eglCreateImageKHR() failed. err=0x%4x",
1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    eglGetError());
1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
1731473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
1741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                        (GLeglImageOES)mTextures[index].image);
1751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                GLint error = glGetError();
1761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                if (UNLIKELY(error != GL_NO_ERROR)) {
1771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // this failed, for instance, because we don't support
1781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // NPOT.
1791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // FIXME: do something!
180ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian                    LOGD("layer=%p, glEGLImageTargetTexture2DOES(%p) "
18164a7c6bf5b73c1a401cb2aa8dfad3898166ae326Mathias Agopian                         "failed err=0x%04x",
18264a7c6bf5b73c1a401cb2aa8dfad3898166ae326Mathias Agopian                         this, mTextures[index].image, error);
1831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
1841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                } else {
1851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                    // Everything went okay!
1866950e428feaccc8164b989ef64e771a99948797aMathias Agopian                    mTextures[index].NPOTAdjust = false;
187999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].dirty  = false;
188999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].width  = clientBuf->width;
189999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian                    mTextures[index].height = clientBuf->height;
1901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                }
1911473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
1931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    } else {
1946950e428feaccc8164b989ef64e771a99948797aMathias Agopian        for (int i=0 ; i<NUM_BUFFERS ; i++)
1956950e428feaccc8164b989ef64e771a99948797aMathias Agopian            mTextures[i].image = EGL_NO_IMAGE_KHR;
1966950e428feaccc8164b989ef64e771a99948797aMathias Agopian
1971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        GGLSurface t;
1986950e428feaccc8164b989ef64e771a99948797aMathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
199dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
200dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian                res, strerror(res), buffer.get());
2016950e428feaccc8164b989ef64e771a99948797aMathias Agopian
202dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian        if (res == NO_ERROR) {
2031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            if (UNLIKELY(mTextures[0].name == -1U)) {
2041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian                mTextures[0].name = createTexture();
2056950e428feaccc8164b989ef64e771a99948797aMathias Agopian                mTextures[0].width = 0;
2066950e428feaccc8164b989ef64e771a99948797aMathias Agopian                mTextures[0].height = 0;
2071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian            }
2086950e428feaccc8164b989ef64e771a99948797aMathias Agopian            loadTexture(&mTextures[0], dirty, t);
209dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian            buffer->unlock();
2101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2176950e428feaccc8164b989ef64e771a99948797aMathias Agopian    int index = mFrontBufferIndex;
2186950e428feaccc8164b989ef64e771a99948797aMathias Agopian    if (mTextures[index].image == EGL_NO_IMAGE_KHR)
2196950e428feaccc8164b989ef64e771a99948797aMathias Agopian        index = 0;
2201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    GLuint textureName = mTextures[index].name;
2211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (UNLIKELY(textureName == -1LU)) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the texture has not been created yet, this Layer has
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // in fact never been drawn into. this happens frequently with
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // SurfaceView.
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clearWithOpenGL(clip);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
228999543ba26d10ff9879144965d0c0abcb400636aMathias Agopian    drawWithOpenGL(clip, mTextures[index]);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2316950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2336950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> buffer;
234248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
235248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    // this ensures our client doesn't go away while we're accessing
236248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    // the shared area.
237248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    sp<Client> ourClient(client.promote());
238248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    if (ourClient == 0) {
239248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        // oops, the client is already gone
240248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        return buffer;
241248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    }
242248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
2431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    /*
2449779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
2459779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * at any time, especially while we're in the middle of using the
2469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * buffer 'index' as our front buffer.
2471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian     *
2489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
2499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
2509779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
2519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * from Surface::dequeue()
2521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian     */
2539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    status_t err = lcblk->assertReallocate(index);
2549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
255248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    if (err != NO_ERROR) {
256248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        // the surface may have died
257248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        return buffer;
258248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    }
259248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
260248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    uint32_t w, h;
261248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    { // scope for the lock
262248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        Mutex::Autolock _l(mLock);
263248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        w = mWidth;
264248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        h = mHeight;
265248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        buffer = mBuffers[index];
266ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian
267ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian        // destroy() could have been called before we get here, we log it
268ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian        // because it's uncommon, and the code below should handle it
269ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian        LOGW_IF(buffer==0,
270ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian                "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
271ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian                index, w, h);
272ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian
273248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        mBuffers[index].clear();
274248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    }
275248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
2766950e428feaccc8164b989ef64e771a99948797aMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
277ac7f13bc1ac8af99093987ebcb811f3892b49296Mathias Agopian    if (buffer!=0 && buffer->getStrongCount() == 1) {
2786950e428feaccc8164b989ef64e771a99948797aMathias Agopian        err = buffer->reallocate(w, h, mFormat, effectiveUsage);
2799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    } else {
2809779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // here we have to reallocate a new buffer because we could have a
2819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // client in our process with a reference to it (eg: status bar),
2829779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // and we can't release the handle under its feet.
2839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        buffer.clear();
2846950e428feaccc8164b989ef64e771a99948797aMathias Agopian        buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage);
2859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        err = buffer->initCheck();
2861473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    }
2879779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
2889779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err || buffer->handle == 0) {
2899779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE_IF(err || buffer->handle == 0,
2909779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
2919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                this, index, w, h, strerror(-err));
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGD_IF(DEBUG_RESIZE,
294e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
295e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                this, index, w, h, buffer->handle);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
299248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        Mutex::Autolock _l(mLock);
300248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        if (mWidth && mHeight) {
301248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            // and we have new buffer
302248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            mBuffers[index] = buffer;
303248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            // texture is now dirty...
304248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            mTextures[index].dirty = true;
305248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        } else {
306248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            // oops we got killed while we were allocating the buffer
307248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian            buffer.clear();
308248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        }
3096edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian    }
3109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    return buffer;
3116edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian}
3126edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian
3136950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
3146950e428feaccc8164b989ef64e771a99948797aMathias Agopian{
3156950e428feaccc8164b989ef64e771a99948797aMathias Agopian    /*
3166950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used for software rendering, but h/w composition
3176950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
3186950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
3196950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used for h/w rendering and h/w composition
3206950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
3216950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
3226950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
3236950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
3246950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
3256950e428feaccc8164b989ef64e771a99948797aMathias Agopian     */
3266950e428feaccc8164b989ef64e771a99948797aMathias Agopian
3276950e428feaccc8164b989ef64e771a99948797aMathias Agopian    if (mSecure) {
3286950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // secure buffer, don't store it into the GPU
3296950e428feaccc8164b989ef64e771a99948797aMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
3306950e428feaccc8164b989ef64e771a99948797aMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
3316950e428feaccc8164b989ef64e771a99948797aMathias Agopian    } else {
3326950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // it's allowed to modify the usage flags here, but generally
3336950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // the requested flags should be honored.
3346950e428feaccc8164b989ef64e771a99948797aMathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
3356950e428feaccc8164b989ef64e771a99948797aMathias Agopian    }
3366950e428feaccc8164b989ef64e771a99948797aMathias Agopian    return usage;
3376950e428feaccc8164b989ef64e771a99948797aMathias Agopian}
3386950e428feaccc8164b989ef64e771a99948797aMathias Agopian
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& front(drawingState());
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& temp(currentState());
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
344e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian    if ((front.requested_w != temp.requested_w) ||
345e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian        (front.requested_h != temp.requested_h)) {
3469779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // the size changed, we need to ask our client to request a new buffer
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
3489779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    "resize (layer=%p), requested (%dx%d), "
3499779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    "drawing (%d,%d), (%dx%d), (%dx%d)",
350e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                    this,
351e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                    int(temp.requested_w), int(temp.requested_h),
352e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                    int(front.requested_w), int(front.requested_h),
3539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
3549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
3559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
3569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // we're being resized and there is a freeze display request,
3579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // acquire a freeze lock, so that the screen stays put
3589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // until we've redrawn at the new size; this is to avoid
3599779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // glitches upon orientation changes.
3609779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        if (mFlinger->hasFreezeRequest()) {
3619779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            // if the surface is hidden, don't try to acquire the
3629779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            // freeze lock, since hidden surfaces may never redraw
3639779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
3649779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                mFreezeLock = mFlinger->getFreezeLock();
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3677cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian
368bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        // this will make sure LayerBase::doTransaction doesn't update
369bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        // the drawing state's size
370bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        Layer::State& editDraw(mDrawingState);
371bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        editDraw.requested_w = temp.requested_w;
372bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        editDraw.requested_h = temp.requested_h;
373bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian
37470cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian        // record the new size, form this point on, when the client request a
37570cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian        // buffer, it'll get the new size.
37670cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian        setDrawingSize(temp.requested_w, temp.requested_h);
37770cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian
3787cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian        // all buffers need reallocation
3797cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian        lcblk->reallocate();
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (temp.sequence != front.sequence) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFreezeLock.clear();
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return LayerBase::doTransaction(flags);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3939779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopianvoid Layer::setDrawingSize(uint32_t w, uint32_t h) {
3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mWidth = w;
3969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling...
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4059779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    ssize_t buf = lcblk->retireAndLock();
4069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (buf < NO_ERROR) {
4079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        //LOGW("nothing to retire (%s)", strerror(-buf));
4089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // NOTE: here the buffer is locked because we will used
4099779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // for composition later in the loop
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
4139779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // we retired a buffer, which becomes the new front buffer
4149779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFrontBufferIndex = buf;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // get the dirty region
4176950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
4189779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    const Region dirty(lcblk->getDirtyRegion(buf));
4199779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4217cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian    const Layer::State& front(drawingState());
422bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian    if (newFrontBuffer->getWidth()  == front.requested_w &&
423bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        newFrontBuffer->getHeight() == front.requested_h)
424bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian    {
425bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        if ((front.w != front.requested_w) ||
426bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            (front.h != front.requested_h))
427bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        {
428bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // Here we pretend the transaction happened by updating the
429bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // current and drawing states. Drawing state is only accessed
430bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // in this thread, no need to have it locked
431bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            Layer::State& editDraw(mDrawingState);
432bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            editDraw.w = editDraw.requested_w;
433bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            editDraw.h = editDraw.requested_h;
434bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian
435bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // We also need to update the current state so that we don't
436bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // end-up doing too much work during the next transaction.
437bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // NOTE: We actually don't need hold the transaction lock here
438bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // because State::w and State::h are only accessed from
439bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // this thread
440bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            Layer::State& editTemp(currentState());
441bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            editTemp.w = editDraw.w;
442bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            editTemp.h = editDraw.h;
443bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian
444bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // recompute visible region
445bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            recomputeVisibleRegions = true;
446bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian
447bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            // we now have the correct size, unfreeze the screen
448bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian            mFreezeLock.clear();
449bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        }
4507cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian    }
4517cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian
4529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // FIXME: signal an event if we have more buffers waiting
4539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // mFlinger->signalEvent();
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4556950e428feaccc8164b989ef64e771a99948797aMathias Agopian    if (!mPostedDirtyRegion.isEmpty()) {
4566950e428feaccc8164b989ef64e771a99948797aMathias Agopian        reloadTexture( mPostedDirtyRegion );
4576950e428feaccc8164b989ef64e771a99948797aMathias Agopian    }
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip(
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPostedDirtyRegion.clear();
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The dirty region is given in the layer's coordinate space
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // transform the dirty region by the surface's transformation
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // and the global transformation.
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Layer::State& s(drawingState());
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform tr(planeTransform * s.transform);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // At this point, the dirty region is in screen space.
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make sure it's constrained by the visible region (which
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // is in screen space as well).
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::finishPageFlip()
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4839779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    status_t err = lcblk->unlock( mFrontBufferIndex );
4849779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    LOGE_IF(err!=NO_ERROR,
4859779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            "layer %p, buffer=%d wasn't locked!",
4869779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            this, mFrontBufferIndex);
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// ---------------------------------------------------------------------------
4901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
4916cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
4926cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian        SurfaceID id, const sp<Layer>& owner)
4936cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian    : Surface(flinger, id, owner->getIdentity(), owner)
4946cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{
4956cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian}
4966cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian
4976cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
4981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
4991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
5001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
5016950e428feaccc8164b989ef64e771a99948797aMathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
5021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
5036950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> buffer;
5041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    sp<Layer> owner(getOwner());
5051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (owner != 0) {
5069779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
5079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "getBuffer() index (%d) out of range", index);
5089779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        if (uint32_t(index) < NUM_BUFFERS) {
5099779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            buffer = owner->requestBuffer(index, usage);
5109779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        }
5111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    }
5121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    return buffer;
5131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
519