Layer.cpp revision a7f669256f93a593c723f05784ef04d3c7d052bb
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
50cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias AgopianLayer::Layer(SurfaceFlinger* flinger, DisplayID display,
51d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<Client>& client, int32_t i)
52d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    :   LayerBaseClient(flinger, display, client, i),
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    // no OpenGL operation is possible here, since we might not be
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // in the OpenGL thread.
63d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    lcblk = new SharedBufferServer(
64bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            client->ctrlblk, i, mBufferManager.getDefaultBufferCount(),
65d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            getIdentity());
66d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
67d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian   mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // FIXME: must be called from the main UI thread
73bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
74bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
75bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the actual buffers will be destroyed here
77d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    delete lcblk;
78d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
81d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
82d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
83d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
84d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // wake up the condition
85d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    lcblk->setStatus(NO_INIT);
8648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
87cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSurface;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
95bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: Called from the main UI thread
96bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
98f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
99bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
100bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
101bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
102bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mSurface.clear();
103bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
104bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
105bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mWidth = mHeight = 0;
1069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
109f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
112401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
118401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
119ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
120ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
121ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
122ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
123ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
124ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
125ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
126ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
127ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
128401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
129401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
130a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
131a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
132cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
133ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
134cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
1353330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
137ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
138401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
139401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
140401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
141401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
142401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
1439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
149d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
1508f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
1518f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
1528f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
1538f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
1548f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
1558f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
1568f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
15754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#ifdef EGL_ANDROID_image_native_buffer
15857720c384af81327d327ef8b88078f11a750fd05Mathias Agopian    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
159d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
160d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            // not sure what we can do here...
162d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
163d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            goto slowpath;
164076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
16554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    } else
16654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif
16754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    {
168fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
169076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
1703330b203039dea366d4981db1408a460134b2d2cMathias Agopian        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
1710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        LOGE_IF(res, "error %d (%s) locking buffer %p",
1720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                res, strerror(res), buffer.get());
1730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (res == NO_ERROR) {
174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            mBufferManager.loadTexture(dirty, t);
1750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            buffer->unlock();
176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
182d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Texture tex(mBufferManager.getActiveTexture());
183d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (tex.name == -1LU) {
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
185179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
186179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
187179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
188179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
189179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
190179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
191179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
192179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
193179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
194179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
195179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
196179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
197179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
198179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
199179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
200179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
201179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
202179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
203179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
204179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
205179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            clearWithOpenGL(holes);
206179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
209d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    drawWithOpenGL(clip, tex);
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const
213a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
214a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
215a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // NOTE: there is a race here, because mFixedSize is updated in a
216a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // binder transaction. however, it doesn't really matter since it is
217a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // evaluated each time we draw. To be perfectly correct, this flag
218a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        // would have to be associated with a buffer.
219a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian        if (mFixedSize)
220a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian            return true;
221a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    }
222a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    return LayerBase::needsFiltering();
223a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
224a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
225b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
226b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
227b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
228bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // Ensures our client doesn't go away while we're accessing
229b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    // the shared area.
230b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Client> ourClient(client.promote());
231b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (ourClient == 0) {
232b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        // oops, the client is already gone
233b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        return DEAD_OBJECT;
234b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
235b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
236bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
237bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = lcblk->resize(bufferCount);
238bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (err == NO_ERROR)
239bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        mBufferManager.resize(bufferCount);
240b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
241b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
242b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
243b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
244a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
245a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
246a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t usage)
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2483330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
24948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
250a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((reqWidth | reqHeight | reqFormat) < 0)
251a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
252a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
253a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
254a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
255a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
25648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
25748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
25848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    sp<Client> ourClient(client.promote());
25948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (ourClient == 0) {
26048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
26148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
26248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
26348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
264076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
265cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
266cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
267cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
268bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian     *
269cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * Make sure the buffer we're resizing is not the front buffer and has been
270cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * dequeued. Once this condition is asserted, we are guaranteed that this
271cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer cannot become the front buffer under our feet, since we're called
272cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * from Surface::dequeue()
273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
274cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = lcblk->assertReallocate(index);
275cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
27648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (err != NO_ERROR) {
27748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // the surface may have died
27848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
27948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
28048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
281a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, f;
28248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
28348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
284a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight);
285a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        const bool formatChanged    = mReqFormat != reqFormat;
286a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqWidth  = reqWidth;
287a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqHeight = reqHeight;
288a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mReqFormat = reqFormat;
289a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mFixedSize = reqWidth && reqHeight;
290a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        w = reqWidth  ? reqWidth  : mWidth;
291a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        h = reqHeight ? reqHeight : mHeight;
292a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        f = reqFormat ? reqFormat : mFormat;
293d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        buffer = mBufferManager.detachBuffer(index);
294a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (fixedSizeChanged || formatChanged) {
295a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAllExcept(index);
296a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
29748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
29848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
2993330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
3006d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian    if (buffer!=0 && buffer->getStrongCount() == 1) {
301a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        err = buffer->reallocate(w, h, f, effectiveUsage);
302cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
303cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // here we have to reallocate a new buffer because we could have a
304cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // client in our process with a reference to it (eg: status bar),
305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // and we can't release the handle under its feet.
306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        buffer.clear();
307a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = new GraphicBuffer(w, h, f, effectiveUsage);
308cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = buffer->initCheck();
309076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
310cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
311cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
312cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
313cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
3177e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
3187e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
321cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
32248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
323a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
324f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
326f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
327f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
3283330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
3293330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
3303330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
3313330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
3323330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
3333330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3343330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
3353330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
3363330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3373330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
3383330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
3393330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
3403330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
3413330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3423330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
3433330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
3443330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
3453330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
3463330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
3473330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
3483330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
34989141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        // request EGLImage for all buffers
35089141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
3513330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
3543330b203039dea366d4981db1408a460134b2d2cMathias Agopian
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
360a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
361a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            (front.requested_h != temp.requested_h);
362a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
363a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
364cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
366a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
367a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                this,
368a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
369a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(front.requested_w), int(front.requested_h));
370a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
371a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
372a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // we're being resized and there is a freeze display request,
373a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // acquire a freeze lock, so that the screen stays put
374a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // until we've redrawn at the new size; this is to avoid
375a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // glitches upon orientation changes.
376a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
377a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // if the surface is hidden, don't try to acquire the
378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
379a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                }
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
383caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // the drawing state's size
386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            Layer::State& editDraw(mDrawingState);
387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_w = temp.requested_w;
388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_h = temp.requested_h;
389df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size, form this point on, when the client request
391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // a buffer, it'll get the new size.
392a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
3936656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
394a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // all buffers need reallocation
395a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAll();
396a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        } else {
397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size
398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
399a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
401cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
414cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
415cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
419a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const {
420a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mLock);
421a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mFixedSize;
422a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
430cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
431d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf == NOT_ENOUGH_DATA) {
432d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
433d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // retire. The buffer is locked because we will use it
434cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
437d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
438d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf < NO_ERROR) {
439d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
440d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
441d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
442d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
443d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
445d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
446d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", buf);
447d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mPostedDirtyRegion.clear();
448d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        return;
449d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
451cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // get the dirty region
4523330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
453d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
454d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
455d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
456d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
457d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
458d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
459d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
460d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
461d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
462df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
463d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
464d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
465d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
466d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
467d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
468d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
469d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
470d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
471d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
472d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
473d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
474d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
484d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
4858f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
495caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
496caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
497e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
498e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
499e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
500e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
502245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
503245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
504245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
505245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
506245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
507245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
508245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
509245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
510245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
532c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
533c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
5341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
535c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
536c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip()
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
541d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    int buf = mBufferManager.getActiveBufferIndex();
542d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    status_t err = lcblk->unlock( buf );
543d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
5481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
5491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
5501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    SharedBufferStack::Statistics stats = lcblk->getStats();
5521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append( lcblk->dump("      ") );
5531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
5541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
5551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
5561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
5571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
5581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
5591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
5601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
5611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
5621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
5631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
5641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
5651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
5661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
5671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
5681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
5691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
5701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
5711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            pixelFormat(),
5721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            w0, h0, s0, w1, h1, s1,
5731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            getFreezeLock().get(), stats.totalTime);
5741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
5751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
5761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
5771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
580d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
581bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
582bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian      mActiveBuffer(0), mFailover(false)
583bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
584bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
585bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
586bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager()
587d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
588d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
589d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
590bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::resize(size_t size)
591bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
592bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
593bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mNumBuffers = size;
594bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
595d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
596d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
597d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging
598d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
599d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mBufferData[index].buffer;
600d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
601d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
602d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
603d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // TODO: need to validate 'index'
604d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    mActiveBuffer = index;
605d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
606d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
607d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
608d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
609d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mActiveBuffer;
610d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
611d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
612d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
613bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Texture res;
614bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (mFailover) {
615bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        res = mFailoverTexture;
616bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } else {
617bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
618bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
619bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
623bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    const size_t activeBuffer = mActiveBuffer;
624bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData const * const buffers = mBufferData;
625d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
626bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return buffers[activeBuffer].buffer;
627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
628d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
629d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
630d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
631bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
632d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer;
633d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
634bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffer = buffers[index].buffer;
635bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = 0;
636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return buffer;
637d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
638d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
639d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
640d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
641d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
642bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
643d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
644bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = buffer;
645bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].texture.dirty = true;
646d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
647d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
648d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
649d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
650d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
651bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
652bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    size_t num;
653bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    { // scope for the lock
654bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        Mutex::Autolock _l(mLock);
655bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        num = mNumBuffers;
656bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
657bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            buffers[i].buffer = 0;
658bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
659bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
660bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
661bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
662d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
663d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    destroyTexture(&mFailoverTexture, dpy);
664d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
665d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
666d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
667d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
668d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
669d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
670d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    size_t index = mActiveBuffer;
671bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Image& texture(mBufferData[index].texture);
672d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    status_t err = mTextureManager.initEglImage(&texture, dpy, buffer);
673d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // if EGLImage fails, we switch to regular texture mode, and we
674d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    // free all resources associated with using EGLImages.
675d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (err == NO_ERROR) {
676d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mFailover = false;
677d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        destroyTexture(&mFailoverTexture, dpy);
678d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    } else {
679d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mFailover = true;
680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        const size_t num = mNumBuffers;
681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
682d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            destroyTexture(&mBufferData[i].texture, dpy);
683d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        }
684d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
685d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return err;
686d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
687d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
688d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture(
689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const Region& dirty, const GGLSurface& t)
690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
691d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
692d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
693d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
694bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
695bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
696bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->name != -1U) {
697bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        glDeleteTextures(1, &tex->name);
698bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->name = -1U;
699bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
700bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
701bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
702bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
703bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
704bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
705bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// ---------------------------------------------------------------------------
708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
7099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
7109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        SurfaceID id, const sp<Layer>& owner)
7119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    : Surface(flinger, id, owner->getIdentity(), owner)
7129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
7139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
7149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
7159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
716076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
717076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
718076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
719a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
720a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
721076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
7223330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
723076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
724076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
725bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
726bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * requestBuffer() cannot be called from the main thread
727bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
728bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
729bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
730a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
735b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
736b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
737b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    status_t err = DEAD_OBJECT;
738b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Layer> owner(getOwner());
739b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (owner != 0) {
740bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
741bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * setBufferCount() cannot be called from the main thread
742bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
743bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
744bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
745b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        err = owner->setBufferCount(bufferCount);
746b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
747b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
748b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
749b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
754