Layer.cpp revision 96f0819f81293076e652792794a961543e6750d7
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
309cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
319cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopiantemplate <typename T> inline T min(T a, T b) {
45ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    return a<b ? a : b;
46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian}
47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5096f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger,
5196f0819f81293076e652792794a961543e6750d7Mathias Agopian        DisplayID display, const sp<Client>& client)
5296f0819f81293076e652792794a961543e6750d7Mathias Agopian    :   LayerBaseClient(flinger, display, client),
53d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        lcblk(NULL),
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecure(false),
55401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsBlending(true),
56d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mNeedsDithering(false),
57d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mTextureManager(mFlags),
58a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager(mTextureManager),
59a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mWidth(0), mHeight(0), mFixedSize(false)
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
65bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // FIXME: must be called from the main UI thread
66bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
67bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
68bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the actual buffers will be destroyed here
70d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    delete lcblk;
71d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
72d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
7396f0819f81293076e652792794a961543e6750d7Mathias Agopian// TODO: get rid of this
7496f0819f81293076e652792794a961543e6750d7Mathias Agopianvoid Layer::setToken(int32_t token)
7596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
7696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> ourClient(client.promote());
7796f0819f81293076e652792794a961543e6750d7Mathias Agopian
7896f0819f81293076e652792794a961543e6750d7Mathias Agopian    mToken = token;
7996f0819f81293076e652792794a961543e6750d7Mathias Agopian
8096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // no OpenGL operation is possible here, since we might not be
8196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // in the OpenGL thread.
8296f0819f81293076e652792794a961543e6750d7Mathias Agopian    lcblk = new SharedBufferServer(
8396f0819f81293076e652792794a961543e6750d7Mathias Agopian            ourClient->ctrlblk, token, mBufferManager.getDefaultBufferCount(),
8496f0819f81293076e652792794a961543e6750d7Mathias Agopian            getIdentity());
8596f0819f81293076e652792794a961543e6750d7Mathias Agopian
8696f0819f81293076e652792794a961543e6750d7Mathias Agopian   mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
8796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
8896f0819f81293076e652792794a961543e6750d7Mathias Agopian
89d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
91d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
92d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
9396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> ourClient(client.promote());
9496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (ourClient != 0) {
9596f0819f81293076e652792794a961543e6750d7Mathias Agopian        // wake up the condition
9696f0819f81293076e652792794a961543e6750d7Mathias Agopian        lcblk->setStatus(NO_INIT);
9796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
9848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
99cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSurface;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
1069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
107bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: Called from the main UI thread
108bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
110f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
111bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
112bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
113bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
114bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mSurface.clear();
115bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
116bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
117bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mWidth = mHeight = 0;
1189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
121f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
124401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
129401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
130401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
131ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
132ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
133ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
134ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
135ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
136ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
137ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
138ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
139ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
140401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
141401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
142a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
143a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
145ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
146cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
1473330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
149ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
150401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
151401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
152401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
153401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
154401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, this);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
1628f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
1638f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
1648f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
1658f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
1668f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
1678f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
1688f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
16954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer
17057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
171d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
172d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
173d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            // not sure what we can do here...
174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
175d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            goto slowpath;
176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
17754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    } else
17854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif
17954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    {
180fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
1823330b203039dea366d4981db1408a460134b2d2cMathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
1830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
1840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                res, strerror(res), buffer.get());
1850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (res == NO_ERROR) {
186d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            mBufferManager.loadTexture(dirty, t);
1870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            buffer->unlock();
188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
194d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Texture tex(mBufferManager.getActiveTexture());
195d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (tex.name == -1LU) {
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
197179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
198179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
199179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
200179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
201179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
202179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
203179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
204179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
205179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
206179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
207179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
208179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
209179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
210179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
211179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
212179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
213179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
214179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
215179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
216179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
217179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            clearWithOpenGL(holes);
218179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
221d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    drawWithOpenGL(clip, tex);
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const
225a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
226a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
227a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // NOTE: there is a race here, because mFixedSize is updated in a
228a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // binder transaction. however, it doesn't really matter since it is
229a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // evaluated each time we draw. To be perfectly correct, this flag
230a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // would have to be associated with a buffer.
231a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        if (mFixedSize)
232a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian            return true;
233a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    }
234a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    return LayerBase::needsFiltering();
235a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
236a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
237b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
238b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
239b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
240bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // Ensures our client doesn't go away while we're accessing
241b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    // the shared area.
242b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Client> ourClient(client.promote());
243b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (ourClient == 0) {
244b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        // oops, the client is already gone
245b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        return DEAD_OBJECT;
246b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
247b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
248bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
249bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = lcblk->resize(bufferCount);
250bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (err == NO_ERROR)
251bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        mBufferManager.resize(bufferCount);
252b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
253b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
254b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
255b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
256a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
257a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
258a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t usage)
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2603330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
26148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
262a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((reqWidth | reqHeight | reqFormat) < 0)
263a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
264a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
265a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
266a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
267a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
26848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
26948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
27048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    sp<Client> ourClient(client.promote());
27148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (ourClient == 0) {
27248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
27348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
27448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
27548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
276076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
277cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
278cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
279cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
280bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian     *
281cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
282cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
283cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
284cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * from Surface::dequeue()
285076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
286cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->assertReallocate(index);
287cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
28848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (err != NO_ERROR) {
28948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // the surface may have died
29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
29148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
29248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
293a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, f;
29448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
29548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
296a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight);
297a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        const bool formatChanged    = mReqFormat != reqFormat;
298a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqWidth  = reqWidth;
299a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqHeight = reqHeight;
300a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqFormat = reqFormat;
301a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mFixedSize = reqWidth && reqHeight;
302a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        w = reqWidth  ? reqWidth  : mWidth;
303a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        h = reqHeight ? reqHeight : mHeight;
304a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        f = reqFormat ? reqFormat : mFormat;
305d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        buffer = mBufferManager.detachBuffer(index);
306a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (fixedSizeChanged || formatChanged) {
307a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAllExcept(index);
308a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
30948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
31048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
3113330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
3126d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian    if (buffer!=0 && buffer->getStrongCount() == 1) {
313a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        err = buffer->reallocate(w, h, f, effectiveUsage);
314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
315cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // here we have to reallocate a new buffer because we could have a
316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // client in our process with a reference to it (eg: status bar),
317cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // and we can't release the handle under its feet.
318cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        buffer.clear();
319a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = new GraphicBuffer(w, h, f, effectiveUsage);
320cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = buffer->initCheck();
321076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
322cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
323cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
324cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
326cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
3297e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
3307e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
33448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
335a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
336f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
338f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
339f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
3403330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
3413330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
3423330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
3433330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
3443330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
3453330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3463330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
3473330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
3483330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3493330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
3503330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
3513330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3543330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
3553330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
3563330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
3573330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
3583330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
3593330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
3603330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
36189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        // request EGLImage for all buffers
36289141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
3663330b203039dea366d4981db1408a460134b2d2cMathias Agopian
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
372a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
373a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            (front.requested_h != temp.requested_h);
374a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
375a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
376cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
379a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                this,
380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(front.requested_w), int(front.requested_h));
382a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
383a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // we're being resized and there is a freeze display request,
385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // acquire a freeze lock, so that the screen stays put
386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // until we've redrawn at the new size; this is to avoid
387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // glitches upon orientation changes.
388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
389a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // if the surface is hidden, don't try to acquire the
390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
392a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
393a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                }
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
395caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
396a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // the drawing state's size
398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            Layer::State& editDraw(mDrawingState);
399a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_w = temp.requested_w;
400a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_h = temp.requested_h;
401df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
402a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size, form this point on, when the client request
403a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // a buffer, it'll get the new size.
404a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
4056656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
40696f0819f81293076e652792794a961543e6750d7Mathias Agopian            sp<Client> ourClient(client.promote());
40796f0819f81293076e652792794a961543e6750d7Mathias Agopian            if (ourClient != 0) {
40896f0819f81293076e652792794a961543e6750d7Mathias Agopian                // all buffers need reallocation
40996f0819f81293076e652792794a961543e6750d7Mathias Agopian                lcblk->reallocateAll();
41096f0819f81293076e652792794a961543e6750d7Mathias Agopian            }
411a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        } else {
412a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size
413a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
414a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
429cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
430cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
431cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
434a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const {
435a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mLock);
436a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mFixedSize;
437a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
438a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
44596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> ourClient(client.promote());
44696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (ourClient == 0) {
44796f0819f81293076e652792794a961543e6750d7Mathias Agopian        // client died
44896f0819f81293076e652792794a961543e6750d7Mathias Agopian        recomputeVisibleRegions = true;
44996f0819f81293076e652792794a961543e6750d7Mathias Agopian        return;
45096f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
45196f0819f81293076e652792794a961543e6750d7Mathias Agopian
452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
453d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf == NOT_ENOUGH_DATA) {
454d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
455d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // retire. The buffer is locked because we will use it
456cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
459d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
460d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf < NO_ERROR) {
461d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
462d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
463d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
464d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
465d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
466cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
467d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
468d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
469d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mPostedDirtyRegion.clear();
470d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        return;
471d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // get the dirty region
4743330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
484df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
485d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
498d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
5078f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
513d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
517caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
518caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
519e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
520e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
521e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
522e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
524245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
525245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
526245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
527245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
528245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
529245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
530245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
531245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
532245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
554c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
555c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
5561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
557c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
558c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip()
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
56396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> ourClient(client.promote());
56496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (ourClient != 0) {
56596f0819f81293076e652792794a961543e6750d7Mathias Agopian        int buf = mBufferManager.getActiveBufferIndex();
56696f0819f81293076e652792794a961543e6750d7Mathias Agopian        status_t err = lcblk->unlock( buf );
56796f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
56896f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
5731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
5741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
5751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    SharedBufferStack::Statistics stats = lcblk->getStats();
5771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append( lcblk->dump("      ") );
5781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
5791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
5801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
5811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
5821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
5831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
5841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
5851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
5861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
5871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
5881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
5891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
5901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
5911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
5921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
5931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
5941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
5951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
5961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            pixelFormat(),
5971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            w0, h0, s0, w1, h1, s1,
5981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            getFreezeLock().get(), stats.totalTime);
5991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
6001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
6011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
6021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
605d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
606bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
607bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian      mActiveBuffer(0), mFailover(false)
608bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
609bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
610bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
611bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager()
612d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
613d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
614d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
615bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size)
616bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
617bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
618bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mNumBuffers = size;
619bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging
623d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
624d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mBufferData[index].buffer;
625d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
626d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
628d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // TODO: need to validate 'index'
629d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    mActiveBuffer = index;
630d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
631d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
632d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
633d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
634d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mActiveBuffer;
635d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
637d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
638bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Texture res;
639bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (mFailover) {
640bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        res = mFailoverTexture;
641bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } else {
642bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
643bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
644bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
645d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
646d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
647d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
648bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    const size_t activeBuffer = mActiveBuffer;
649bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData const * const buffers = mBufferData;
650d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
651bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return buffers[activeBuffer].buffer;
652d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
653d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
654d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
655d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
656bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
657d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer;
658d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
659bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffer = buffers[index].buffer;
660bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = 0;
661d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return buffer;
662d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
663d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
664d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
665d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
666d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
667bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
668d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
669bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = buffer;
670bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].texture.dirty = true;
671d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
672d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
673d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
674d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
675d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
676bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
677bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    size_t num;
678bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    { // scope for the lock
679bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        Mutex::Autolock _l(mLock);
680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        num = mNumBuffers;
681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
682bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            buffers[i].buffer = 0;
683bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
684bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
685bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
686bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
687d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
688d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    destroyTexture(&mFailoverTexture, dpy);
689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
691d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
692d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
693d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
694d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
695d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    size_t index = mActiveBuffer;
696bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Image& texture(mBufferData[index].texture);
697d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    status_t err = mTextureManager.initEglImage(&texture, dpy, buffer);
698d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // if EGLImage fails, we switch to regular texture mode, and we
699d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // free all resources associated with using EGLImages.
700d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (err == NO_ERROR) {
701d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mFailover = false;
702d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        destroyTexture(&mFailoverTexture, dpy);
703d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    } else {
704d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mFailover = true;
705bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        const size_t num = mNumBuffers;
706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            destroyTexture(&mBufferData[i].texture, dpy);
708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        }
709d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
710d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return err;
711d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
712d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
713d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture(
714d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const Region& dirty, const GGLSurface& t)
715d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
716d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
717d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
718d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
719bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
720bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
721bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->name != -1U) {
722bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        glDeleteTextures(1, &tex->name);
723bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->name = -1U;
724bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
725bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
726bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
727bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
728bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
729bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
730bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
731bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
732d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// ---------------------------------------------------------------------------
733d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
7349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
73596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Layer>& owner)
73696f0819f81293076e652792794a961543e6750d7Mathias Agopian    : Surface(flinger, owner->getIdentity(), owner)
7379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
7389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
7399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
7409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
744a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
745a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
7473330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
750bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
751bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * requestBuffer() cannot be called from the main thread
752bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
753bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
754bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
755a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
757076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
760b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
761b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    status_t err = DEAD_OBJECT;
763b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Layer> owner(getOwner());
764b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (owner != 0) {
765bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
766bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * setBufferCount() cannot be called from the main thread
767bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
768bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
769bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
770b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        err = owner->setBufferCount(bufferCount);
771b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
772b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
773b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
774b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
779