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>
30000479f9e325b4e426a67033abd92d47da412725Mathias Agopian
31000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include <surfaceflinger/Surface.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clz.h"
34781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian#include "GLExtensions.h"
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Layer.h"
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SurfaceFlinger.h"
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_RESIZE    0
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45967dce306267109a6e8aec408b65609ac5642a03Mathias Agopiantemplate <typename T> inline T min(T a, T b) {
46967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    return a<b ? a : b;
47967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian}
48967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias AgopianLayer::Layer(SurfaceFlinger* flinger,
52593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        DisplayID display, const sp<Client>& client)
53593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian    :   LayerBaseClient(flinger, display, client),
54781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian        mGLExtensions(GLExtensions::getInstance()),
55cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian        mNeedsBlending(true),
569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        mNeedsDithering(false),
577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        mSecure(false),
58781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian        mTextureManager(),
592be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        mBufferManager(mTextureManager),
60025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false),
61025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        mBypassState(false)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
63afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopian    setDestroyer(this);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayer::~Layer()
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
68898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    // FIXME: must be called from the main UI thread
69898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
70898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    mBufferManager.destroy(dpy);
71898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian
727623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    // we can use getUserClientUnsafe here because we know we're
737623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    // single-threaded at that point.
747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
757623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (ourClient != 0) {
767623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        ourClient->detachLayer(this);
777623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    }
789f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
799f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
80afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopianvoid Layer::destroy(RefBase const* base) {
81afffa8fa9f82a7343e1158bf921931fd3e3df615Mathias Agopian    mFlinger->destroyLayer(static_cast<LayerBase const*>(base));
826f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian}
836f96080f333c70104424f42ac263c4c9c7a9dd2aMathias Agopian
847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient,
857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        SharedClient* sharedClient, int32_t token)
86593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian{
875e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    sp<SharedBufferServer> lcblk = new SharedBufferServer(
887623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            sharedClient, token, mBufferManager.getDefaultBufferCount(),
897623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            getIdentity());
90593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian
917623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
925e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
935e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    LOGE_IF(err != NO_ERROR,
945e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian            "ClientRef::setToken(%p, %p, %u) failed",
955e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian            userClient.get(), lcblk.get(), token);
965e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
975e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    if (err == NO_ERROR) {
985e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        // we need to free the buffers associated with this surface
997623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    }
100593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian
1017623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return err;
1027623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
103593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian
1047623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::getToken() const
1057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{
1067623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return mUserClientRef.getToken();
107593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian}
108593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian
1095e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::getClient() const
1105e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{
1115e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    return mUserClientRef.getClient();
1125e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian}
1135e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
1149f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
1159f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// in the purgatory list
1169f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianvoid Layer::onRemoved()
1179f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
1187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
1197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
1207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (lcblk) {
121593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        // wake up the condition
122593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        lcblk->setStatus(NO_INIT);
123593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian    }
124248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian}
1259779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
1261473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
128cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian    return mSurface;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1316edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            PixelFormat format, uint32_t flags)
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
134cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // this surfaces pixel format
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PixelFormatInfo info;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err) return err;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
139cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // the display's pixel format
140cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
141967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    uint32_t const maxSurfaceDims = min(
142967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
143967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
144967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    // never allow a surface larger than what our underlying GL implementation
145967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    // can handle.
146967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
147967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian        return BAD_VALUE;
148967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    }
149967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
150cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    PixelFormatInfo displayInfo;
151cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
152351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
153351a7073fb60eb3534ec8c69ab263f057a124500Mathias Agopian
1549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mFormat = format;
155967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    mWidth  = w;
1569779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
157c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
158c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian    mReqFormat = format;
159c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian    mReqWidth = w;
160c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian    mReqHeight = h;
161c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
1626950e428feaccc8164b989ef64e771a99948797aMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
164967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
165cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    // we use the red index
166cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
167cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
168cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
169cc934763c3fc789f53edb64de16fc36d43c3705dMathias Agopian
170cf8b94562c7cbd5c7ced01dca9bbca25011a04e8Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, this);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
177083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian    if (buffer == NULL) {
178083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian        // this situation can happen if we ran out of memory for instance.
179083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian        // not much we can do. continue to use whatever texture was bound
180083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian        // to this context.
181083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian        return;
182083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian    }
183083a557c25e0032bc4900f335b6643d0badd09ceMathias Agopian
184781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    if (mGLExtensions.haveDirectTexture()) {
1859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
1869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
1879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian            // not sure what we can do here...
1889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian            goto slowpath;
1891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
190781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    } else {
1911d211f8ee0b422a3a741c3f88246c7c72ce483b0Mathias Agopianslowpath:
1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        GGLSurface t;
193c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
194c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
195c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
196c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian                    res, strerror(res), buffer.get());
197c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian            if (res == NO_ERROR) {
198c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian                mBufferManager.loadTexture(dirty, t);
199c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian                buffer->unlock();
200c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian            }
201c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian        } else {
202c817b22055f094e5fd640952e05821f288107eb3Mathias Agopian            // we can't do anything
2031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian        }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
207597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopianvoid Layer::drawForSreenShot() const
208597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian{
2091989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian    const bool currentFiltering = mNeedsFiltering;
2101989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = true;
211597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian    LayerBase::drawForSreenShot();
2121989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
213597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian}
214597c7f67b5f2491c6098a1de241a3f0fd274688aMathias Agopian
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2179f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    Texture tex(mBufferManager.getActiveTexture());
2189f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    if (tex.name == -1LU) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the texture has not been created yet, this Layer has
2202df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // in fact never been drawn into. This happens frequently with
2212df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // SurfaceView because the WindowManager can't know when the client
2222df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // has drawn the first time.
2232df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian
2242df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
2252df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // we just skip this update.
2262df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian
2272df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // figure out if there is something below us
2282df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        Region under;
2292df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
2302df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        const size_t count = drawingLayers.size();
2312df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
2322df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
2332df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
2342df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian                break;
2352df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian            under.orSelf(layer->visibleRegionScreen);
2362df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        }
2372df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        // if not everything below us is covered, we plug the holes!
2382df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        Region holes(clip.subtract(under));
2392df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        if (!holes.isEmpty()) {
240f8b4b4408cb864bf604608221eafa9d37323d348Mathias Agopian            clearWithOpenGL(holes, 0, 0, 0, 1);
2412df6f515675917a7a2812cf35faa5a1f47a6305fMathias Agopian        }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
244025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
245025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS
246025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
247025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    if ((buffer != NULL) && (buffer->transform)) {
248025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // Here we have a "bypass" buffer, but we need to composite it
249025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // most likely because it's not fullscreen anymore.
250025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // Since the buffer may have a transformation applied by the client
251025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // we need to inverse this transformation here.
252025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
253025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // calculate the inverse of the buffer transform
254025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        const uint32_t mask = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H;
255025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        const uint32_t bufferTransformInverse = buffer->transform ^ mask;
256025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
257025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // To accomplish the inverse transform, we use "mBufferTransform"
258025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // which is not used by Layer.cpp
259025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        const_cast<Layer*>(this)->mBufferTransform = bufferTransformInverse;
260025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        drawWithOpenGL(clip, tex);
261025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // reset to "no transfrom"
262025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        const_cast<Layer*>(this)->mBufferTransform = 0;
263025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        return;
264025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    }
265025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif
266025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
2679f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    drawWithOpenGL(clip, tex);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
270923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopianbool Layer::needsFiltering() const
271923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian{
272923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
2731989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian        // if our buffer is not the same size than ourselves,
2741989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian        // we need filtering.
2751989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian        Mutex::Autolock _l(mLock);
2761989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian        if (mNeedsScaling)
277923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian            return true;
278923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian    }
279923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian    return LayerBase::needsFiltering();
280923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian}
281923770333574fd71674781a9a62f40e8acaf5ef1Mathias Agopian
28259751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian
28359751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
28459751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{
2857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
2867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
2877623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (!lcblk) {
28859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian        // oops, the client is already gone
28959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian        return DEAD_OBJECT;
29059751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    }
29159751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian
292898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
293898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    status_t err = lcblk->resize(bufferCount);
294898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    if (err == NO_ERROR)
295898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        mBufferManager.resize(bufferCount);
29659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian
29759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    return err;
29859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian}
29959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian
3002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
3012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
3022be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        uint32_t usage)
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3046950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> buffer;
305248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
3067623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
3072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        return buffer;
3082be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian
3092be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
3102be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        return buffer;
3112be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian
312248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    // this ensures our client doesn't go away while we're accessing
313248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    // the shared area.
3147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
3157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
3167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (!lcblk) {
317248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        // oops, the client is already gone
318248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        return buffer;
319248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    }
320248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
3211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    /*
3229779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
3239779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * at any time, especially while we're in the middle of using the
3249779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian     * buffer 'index' as our front buffer.
3251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian     */
326248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
327025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    uint32_t w, h, f, bypass;
328248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    { // scope for the lock
329248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        Mutex::Autolock _l(mLock);
330c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
331025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        bypass = mBypassState;
332025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
333c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        // zero means default
3341989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian        mFixedSize = reqWidth && reqHeight;
335c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        if (!reqFormat) reqFormat = mFormat;
336c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        if (!reqWidth)  reqWidth = mWidth;
337c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        if (!reqHeight) reqHeight = mHeight;
338c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
339c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        w = reqWidth;
340c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        h = reqHeight;
341c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        f = reqFormat;
342c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
343c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
344c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian                (reqFormat != mReqFormat)) {
345c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian            mReqWidth  = reqWidth;
346c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian            mReqHeight = reqHeight;
347c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian            mReqFormat = reqFormat;
3481989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
349c51114fe044769d078dd9776f790b881c2a20caeMathias Agopian
3502be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            lcblk->reallocateAllExcept(index);
3512be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        }
352248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian    }
353248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian
35451c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian    // here we have to reallocate a new buffer because the buffer could be
35551c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian    // used as the front buffer, or by a client in our process
35651c70e3e41ee8bedc1d951a06a74202dafa13009Mathias Agopian    // (eg: status bar), and we can't release the handle under its feet.
357025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    uint32_t effectiveUsage = getEffectiveUsage(usage);
358025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
359025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    status_t err = NO_MEMORY;
360025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
361025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#ifdef USE_COMPOSITION_BYPASS
362025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    if (!mSecure && bypass && (effectiveUsage & GRALLOC_USAGE_HW_RENDER)) {
363025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // always allocate a buffer matching the screen size. the size
364025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        // may be different from (w,h) if the buffer is rotated.
365025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        const DisplayHardware& hw(graphicPlane(0).displayHardware());
366025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        int32_t w = hw.getWidth();
367025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        int32_t h = hw.getHeight();
368025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        int32_t f = hw.getFormat();
369025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
370025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        buffer = new GraphicBuffer(w, h, f, effectiveUsage | GRALLOC_USAGE_HW_FB);
371025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        err = buffer->initCheck();
372025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        buffer->transform = uint8_t(getOrientation());
373025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
374025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        if (err != NO_ERROR) {
375025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            // allocation didn't succeed, probably because an older bypass
376025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            // window hasn't released all its resources yet.
377025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            ClientRef::Access sharedClient(mUserClientRef);
378025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            SharedBufferServer* lcblk(sharedClient.get());
379025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            if (lcblk) {
380025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian                // all buffers need reallocation
381025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian                lcblk->reallocateAll();
382025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            }
383025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        }
384025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    }
385025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian#endif
386025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
387025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    if (err != NO_ERROR) {
388025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        buffer = new GraphicBuffer(w, h, f, effectiveUsage);
389025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        err = buffer->initCheck();
390025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    }
3919779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
3929779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err || buffer->handle == 0) {
393e869aee382cfe01d42dffba4912458a16bb791fbMathias Agopian        GraphicBuffer::dumpAllocationsToSystemLog();
3949779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE_IF(err || buffer->handle == 0,
3959779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
3969779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian                this, index, w, h, strerror(-err));
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3989779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGD_IF(DEBUG_RESIZE,
399e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
400e1b6f24423d61b7892e4a59f5a65b04231526712Mathias Agopian                this, index, w, h, buffer->handle);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4039779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
404248b5bd51e325107f8119b564db6a06ac51c232aMathias Agopian        Mutex::Autolock _l(mLock);
4052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
4066edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian    }
4079779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    return buffer;
4086edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian}
4096edf5af578c1ab1fcd44b7c08ca371456e4b7430Mathias Agopian
4106950e428feaccc8164b989ef64e771a99948797aMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
4116950e428feaccc8164b989ef64e771a99948797aMathias Agopian{
4126950e428feaccc8164b989ef64e771a99948797aMathias Agopian    /*
4136950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used for software rendering, but h/w composition
4146950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
4156950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
4166950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used for h/w rendering and h/w composition
4176950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
4186950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
4196950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
4206950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
4216950e428feaccc8164b989ef64e771a99948797aMathias Agopian     *
4226950e428feaccc8164b989ef64e771a99948797aMathias Agopian     */
4236950e428feaccc8164b989ef64e771a99948797aMathias Agopian
4246950e428feaccc8164b989ef64e771a99948797aMathias Agopian    if (mSecure) {
4256950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // secure buffer, don't store it into the GPU
4266950e428feaccc8164b989ef64e771a99948797aMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
4276950e428feaccc8164b989ef64e771a99948797aMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
4286950e428feaccc8164b989ef64e771a99948797aMathias Agopian    } else {
4296950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // it's allowed to modify the usage flags here, but generally
4306950e428feaccc8164b989ef64e771a99948797aMathias Agopian        // the requested flags should be honored.
431aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian        // request EGLImage for all buffers
432aca2ee8a7045e6b3d0399736d7d1adf7e1dbf825Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
4336950e428feaccc8164b989ef64e771a99948797aMathias Agopian    }
4346950e428feaccc8164b989ef64e771a99948797aMathias Agopian    return usage;
4356950e428feaccc8164b989ef64e771a99948797aMathias Agopian}
4366950e428feaccc8164b989ef64e771a99948797aMathias Agopian
437025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopianbool Layer::setBypass(bool enable)
438025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian{
439025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    Mutex::Autolock _l(mLock);
440025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
441025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    if (mNeedsScaling || mNeedsFiltering) {
442025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        return false;
443025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    }
444025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
445025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    if (mBypassState != enable) {
446025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        mBypassState = enable;
447025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        ClientRef::Access sharedClient(mUserClientRef);
448025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        SharedBufferServer* lcblk(sharedClient.get());
449025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        if (lcblk) {
450025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            // all buffers need reallocation
451025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            lcblk->reallocateAll();
452025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian        }
453025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    }
454025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
455025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian    return true;
456025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian}
457025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian
458ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopianvoid Layer::updateBuffersOrientation()
459ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian{
460ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian    sp<GraphicBuffer> buffer(getBypassBuffer());
461ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian    if (buffer != NULL && mOrientation != buffer->transform) {
462ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian        ClientRef::Access sharedClient(mUserClientRef);
463ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian        SharedBufferServer* lcblk(sharedClient.get());
464ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian        if (lcblk) { // all buffers need reallocation
465ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian            lcblk->reallocateAll();
466ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian        }
467ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian    }
468ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian}
469ee5a3aca5752f201b69fe0307414ca16ca492f0eMathias Agopian
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& front(drawingState());
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Layer::State& temp(currentState());
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4752be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
4762be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            (front.requested_h != temp.requested_h);
4772be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian
4782be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian    if (sizeChanged) {
4799779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // the size changed, we need to ask our client to request a new buffer
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
4812be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
4822be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                this,
4832be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
4842be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                int(front.requested_w), int(front.requested_h));
4852be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian
4862be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        if (!isFixedSize()) {
4872be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // we're being resized and there is a freeze display request,
4882be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // acquire a freeze lock, so that the screen stays put
4892be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // until we've redrawn at the new size; this is to avoid
4902be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // glitches upon orientation changes.
4912be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
4922be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                // if the surface is hidden, don't try to acquire the
4932be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
4942be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
4952be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
4962be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian                }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4987cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian
4992be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
5002be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // the drawing state's size
5012be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            Layer::State& editDraw(mDrawingState);
5022be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            editDraw.requested_w = temp.requested_w;
5032be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            editDraw.requested_h = temp.requested_h;
504bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian
5052be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // record the new size, form this point on, when the client request
5062be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // a buffer, it'll get the new size.
5072be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
50870cab91229c3c2ca4bb75ab63b552ac7d1a6a8bbMathias Agopian
5097623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            ClientRef::Access sharedClient(mUserClientRef);
5107623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            SharedBufferServer* lcblk(sharedClient.get());
5117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            if (lcblk) {
512593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian                // all buffers need reallocation
513593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian                lcblk->reallocateAll();
514593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian            }
5152be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        } else {
5162be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            // record the new size
5172be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
5182be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5209779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (temp.sequence != front.sequence) {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFreezeLock.clear();
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return LayerBase::doTransaction(flags);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5322be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
5339779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    Mutex::Autolock _l(mLock);
5349779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mWidth = w;
5359779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    mHeight = h;
5361989af22b5aa94430c7a43e13f3307d25be8c837Mathias Agopian    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5392be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopianbool Layer::isFixedSize() const {
5402be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian    Mutex::Autolock _l(mLock);
5412be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian    return mFixedSize;
5422be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian}
5432be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pageflip handling...
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
5517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
5527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (!lcblk) {
553593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        // client died
554593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        recomputeVisibleRegions = true;
555593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        return;
556593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian    }
557593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian
5589779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    ssize_t buf = lcblk->retireAndLock();
5599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    if (buf == NOT_ENOUGH_DATA) {
5609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
5619f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        // retire. The buffer is locked because we will use it
5629779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // for composition later in the loop
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5659e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian
5669f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    if (buf < NO_ERROR) {
5677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
5689e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        mPostedDirtyRegion.clear();
5699e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        return;
5709e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian    }
5719e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian
5729779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    // we retired a buffer, which becomes the new front buffer
5739f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
5747623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
5759f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        mPostedDirtyRegion.clear();
5769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        return;
5779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5796950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
5809e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian    if (newFrontBuffer != NULL) {
581e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian        // get the dirty region
5829e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // compute the posted region
5839e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
5849e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
5859e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian
5869e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // update the layer size and release freeze-lock
5879e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        const Layer::State& front(drawingState());
5889e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
5899e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
590bd23e30de410761af8c68afd8c4b27990e7a099aMathias Agopian        {
5919e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            if ((front.w != front.requested_w) ||
5929e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                (front.h != front.requested_h))
5939e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            {
5949e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // Here we pretend the transaction happened by updating the
5959e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // current and drawing states. Drawing state is only accessed
5969e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // in this thread, no need to have it locked
5979e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                Layer::State& editDraw(mDrawingState);
5989e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                editDraw.w = editDraw.requested_w;
5999e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                editDraw.h = editDraw.requested_h;
6009e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian
6019e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // We also need to update the current state so that we don't
6029e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // end-up doing too much work during the next transaction.
6039e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // NOTE: We actually don't need hold the transaction lock here
6049e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // because State::w and State::h are only accessed from
6059e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // this thread
6069e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                Layer::State& editTemp(currentState());
6079e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                editTemp.w = editDraw.w;
6089e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                editTemp.h = editDraw.h;
6099e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian
6109e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                // recompute visible region
6119e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian                recomputeVisibleRegions = true;
6129e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            }
61346b2df153fccf7f918ee5d7d747c208bdd2d55f4Mathias Agopian
6149e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            // we now have the correct size, unfreeze the screen
6159e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian            mFreezeLock.clear();
6169e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        }
617e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian
618e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian        // get the crop region
619e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian        setBufferCrop( lcblk->getCrop(buf) );
620e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian
621e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian        // get the transformation
622e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian        setBufferTransform( lcblk->getTransform(buf) );
623e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian
6249e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian    } else {
6259e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // this should not happen unless we ran out of memory while
6269e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // allocating the buffer. we're hoping that things will get back
6279e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // to normal the next time the app tries to draw into this buffer.
6289e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        // meanwhile, pretend the screen didn't update.
6299e3d693b1895010f3a2dc1efaf11389da8557cb8Mathias Agopian        mPostedDirtyRegion.clear();
6307cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian    }
6317cf03bace826631259aaa5ddc87a517e13bdee17Mathias Agopian
632e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian    if (lcblk->getQueuedCount()) {
633e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian        // signal an event if we have more buffers waiting
634e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian        mFlinger->signalEvent();
635e05f07dffa196d6403733b26317faa9f267d518fMathias Agopian    }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
637a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
638a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
639a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
640a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
641a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
642a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * update but repainted the buffer with appropriate content (after a
643a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     * resize for instance).
644a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian     */
645a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian    reloadTexture( mPostedDirtyRegion );
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Layer::unlockPageFlip(
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPostedDirtyRegion.clear();
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The dirty region is given in the layer's coordinate space
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // transform the dirty region by the surface's transformation
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // and the global transformation.
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Layer::State& s(drawingState());
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Transform tr(planeTransform * s.transform);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // At this point, the dirty region is in screen space.
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make sure it's constrained by the visible region (which
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // is in screen space as well).
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6675469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian    if (visibleRegionScreen.isEmpty()) {
6685469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian        // an invisible layer should not hold a freeze-lock
6699bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        // (because it may never be updated and therefore never release it)
6705469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian        mFreezeLock.clear();
6715469a4ac1c5073bde2c7caf8540a459c8fb759cdMathias Agopian    }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749bce8737f2f7581ade57445286aa150de051ff89Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
6759bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian{
6769bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
6779bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian
6787623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
6797623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
6807623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    uint32_t totalTime = 0;
6817623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (lcblk) {
6827623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        SharedBufferStack::Statistics stats = lcblk->getStats();
6837623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        totalTime= stats.totalTime;
6847623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        result.append( lcblk->dump("      ") );
6857623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    }
6867623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
6879bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
6889bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
6899bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
6909bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
6919bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    if (buf0 != 0) {
6929bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        w0 = buf0->getWidth();
6939bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        h0 = buf0->getHeight();
6949bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        s0 = buf0->getStride();
6959bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    }
6969bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    if (buf1 != 0) {
6979bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        w1 = buf1->getWidth();
6989bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        h1 = buf1->getHeight();
6999bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian        s1 = buf1->getStride();
7009bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    }
7019bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    snprintf(buffer, SIZE,
7029bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian            "      "
7039bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
704025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            " freezeLock=%p, bypass=%d, dq-q-time=%u us\n",
7057623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian            mFormat, w0, h0, s0, w1, h1, s1,
706025005f562f695c3b1785745c2e5c184fc3a2330Mathias Agopian            getFreezeLock().get(), mBypassState, totalTime);
7079bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian
7089bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian    result.append(buffer);
7099bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian}
7109bce8737f2f7581ade57445286aa150de051ff89Mathias Agopian
7111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// ---------------------------------------------------------------------------
7121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
7137623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::ClientRef()
7145e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    : mControlBlock(0), mToken(-1) {
7157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7177623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::~ClientRef() {
7187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7197623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7207623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianint32_t Layer::ClientRef::getToken() const {
7217623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    Mutex::Autolock _l(mLock);
7227623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return mToken;
7237623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7247623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7255e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const {
7265e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    Mutex::Autolock _l(mLock);
7275e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    return mUserClient.promote();
7285e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian}
7295e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
7307623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
7315e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        const sp<SharedBufferServer>& sharedClient, int32_t token) {
7327623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    Mutex::Autolock _l(mLock);
7335e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
7345e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    { // scope for strong mUserClient reference
7355e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        sp<UserClient> userClient(mUserClient.promote());
7365e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        if (mUserClient != 0 && mControlBlock != 0) {
7375e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian            mControlBlock->setStatus(NO_INIT);
7385e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        }
7395e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    }
7405e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
7417623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    mUserClient = uc;
7427623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    mToken = token;
7435e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    mControlBlock = sharedClient;
7447623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return NO_ERROR;
7457623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7467623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7477623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
7487623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return mUserClient.promote();
7497623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7507623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7517623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// this class gives us access to SharedBufferServer safely
7527623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// it makes sure the UserClient (and its associated shared memory)
7537623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// won't go away while we're accessing it.
7547623da435e45c7c03ef6a00a43675deb6645f070Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref)
7555e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian    : mControlBlock(0)
7567623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian{
7577623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    Mutex::Autolock _l(ref.mLock);
7587623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    mUserClientStrongRef = ref.mUserClient.promote();
7597623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (mUserClientStrongRef != 0)
7605e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian        mControlBlock = ref.mControlBlock;
7615e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian}
7625e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian
7635e14010b1fc066dfcbc0a577d59492687c99667dMathias AgopianLayer::ClientRef::Access::~Access()
7645e14010b1fc066dfcbc0a577d59492687c99667dMathias Agopian{
7657623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian}
7667623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7677623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian// ---------------------------------------------------------------------------
7687623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian
7699f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
770898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
7717623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian      mActiveBuffer(-1), mFailover(false)
772898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{
773898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian}
774898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian
775898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias AgopianLayer::BufferManager::~BufferManager()
7769f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
7779f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
7789f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
779898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size)
780898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{
781898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    Mutex::Autolock _l(mLock);
782898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    mNumBuffers = size;
783898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    return NO_ERROR;
7849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
7859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
7869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// only for debugging
7879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
7889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return mBufferData[index].buffer;
7899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
7909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
7919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
7929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    mActiveBuffer = index;
7939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return NO_ERROR;
7949f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
7959f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
7969f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
7979f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return mActiveBuffer;
7989f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
7999f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8009f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
801898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    Texture res;
8027623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (mFailover || mActiveBuffer<0) {
803898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        res = mFailoverTexture;
804898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    } else {
805898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
806898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    }
807898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    return res;
8089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8099f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8109f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
8117623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    sp<GraphicBuffer> result;
8127623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    const ssize_t activeBuffer = mActiveBuffer;
8137623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (activeBuffer >= 0) {
8147623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        BufferData const * const buffers = mBufferData;
8157623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        Mutex::Autolock _l(mLock);
8167623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian        result = buffers[activeBuffer].buffer;
8177623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    }
8187623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    return result;
8199f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8209f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8219f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
8229f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
823898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    BufferData* const buffers = mBufferData;
8249f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    sp<GraphicBuffer> buffer;
8259f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    Mutex::Autolock _l(mLock);
826898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    buffer = buffers[index].buffer;
827898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    buffers[index].buffer = 0;
8289f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return buffer;
8299f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8309f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8319f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
8329f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        const sp<GraphicBuffer>& buffer)
8339f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
834898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    BufferData* const buffers = mBufferData;
8359f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    Mutex::Autolock _l(mLock);
836898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    buffers[index].buffer = buffer;
837898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    buffers[index].texture.dirty = true;
8389f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return NO_ERROR;
8399f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8409f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8419f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
8429f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
843898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    BufferData* const buffers = mBufferData;
844898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    size_t num;
845898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    { // scope for the lock
846898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        Mutex::Autolock _l(mLock);
847898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        num = mNumBuffers;
848898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
849898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian            buffers[i].buffer = 0;
850898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        }
851898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    }
852898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
853898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
8549f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    }
8559f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    destroyTexture(&mFailoverTexture, dpy);
8569f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return NO_ERROR;
8579f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8589f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8599f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
8609f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        const sp<GraphicBuffer>& buffer)
8619f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
8627623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    status_t err = NO_INIT;
8637623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    ssize_t index = mActiveBuffer;
8647623da435e45c7c03ef6a00a43675deb6645f070Mathias Agopian    if (index >= 0) {
865781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian        if (!mFailover) {
866781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            Image& texture(mBufferData[index].texture);
867781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            err = mTextureManager.initEglImage(&texture, dpy, buffer);
868781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            // if EGLImage fails, we switch to regular texture mode, and we
869781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            // free all resources associated with using EGLImages.
870781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            if (err == NO_ERROR) {
871781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                mFailover = false;
872781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                destroyTexture(&mFailoverTexture, dpy);
873781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            } else {
874781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                mFailover = true;
875781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                const size_t num = mNumBuffers;
876781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                for (size_t i=0 ; i<num ; i++) {
877781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                    destroyTexture(&mBufferData[i].texture, dpy);
878781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian                }
879330dd304a471d260a73e342a240921c03c825f99Andreas Huber            }
880781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian        } else {
881781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            // we failed once, don't try again
882781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            err = BAD_VALUE;
8839f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        }
8849f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    }
8859f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return err;
8869f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8879f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
8889f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopianstatus_t Layer::BufferManager::loadTexture(
8899f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian        const Region& dirty, const GGLSurface& t)
8909f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian{
8919f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
8929f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian}
8939f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
894898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
895898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian{
896898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    if (tex->name != -1U) {
897898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        glDeleteTextures(1, &tex->name);
898898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        tex->name = -1U;
899898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    }
900898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
901898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
902898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
903898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    }
904898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian    return NO_ERROR;
905898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian}
906898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian
9079f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian// ---------------------------------------------------------------------------
9089f2c4fd9a14ea79e4cbbd3ab8925794711a6411cMathias Agopian
9096cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
910593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian        const sp<Layer>& owner)
911593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian    : Surface(flinger, owner->getIdentity(), owner)
9126cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian{
9136cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian}
9146cf0db228ca275dfcda57d79c55e5fa306809632Mathias Agopian
9156cf0db228ca275dfcda57d79c55e5fa306809632Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
9161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
9171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
9181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
9192be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
9202be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
9211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{
9226950e428feaccc8164b989ef64e771a99948797aMathias Agopian    sp<GraphicBuffer> buffer;
9231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    sp<Layer> owner(getOwner());
9241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    if (owner != 0) {
925898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        /*
926898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * requestBuffer() cannot be called from the main thread
927898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
928898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * on conditions updated my the main thread.
929898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         */
9302be352adab7f11646fda7c0240e496bbb37f7bd1Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
9311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    }
9321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    return buffer;
9331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
93559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
93659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian{
93759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    status_t err = DEAD_OBJECT;
93859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    sp<Layer> owner(getOwner());
93959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    if (owner != 0) {
940898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian        /*
941898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * setBufferCount() cannot be called from the main thread
942898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
943898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         * on conditions updated my the main thread.
944898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian         */
94559751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian        err = owner->setBufferCount(bufferCount);
94659751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    }
94759751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian    return err;
94859751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian}
94959751dbf7d8f12aeb5c4c07719b7dbbf1f9b5d4bMathias Agopian
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
954