Layer.cpp revision 5bf3abefb2745bf0c45b0814cfd44b4682060a6c
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"
341f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
38a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopiantemplate <typename T> inline T min(T a, T b) {
47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    return a<b ? a : b;
48ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian}
49ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5296f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger,
5396f0819f81293076e652792794a961543e6750d7Mathias Agopian        DisplayID display, const sp<Client>& client)
5496f0819f81293076e652792794a961543e6750d7Mathias Agopian    :   LayerBaseClient(flinger, display, client),
555bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mGLExtensions(GLExtensions::getInstance()),
57401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsBlending(true),
58d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mNeedsDithering(false),
59b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
6016f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        mProtectedByApp(false),
611f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mTextureManager(),
62a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager(mTextureManager),
635bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian        mWidth(0), mHeight(0),
647ffe3807506da6f052535ca0c790636e41a8e310Eric Hassold        mNeedsScaling(false), mFixedSize(false)
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
70bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // FIXME: must be called from the main UI thread
71bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
73bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
74b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // we can use getUserClientUnsafe here because we know we're
75b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // single-threaded at that point.
76b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ourClient != 0) {
78b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ourClient->detachLayer(this);
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
81d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
82b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient,
83b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        SharedClient* sharedClient, int32_t token)
8496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
85579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    sp<SharedBufferServer> lcblk = new SharedBufferServer(
86b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            sharedClient, token, mBufferManager.getDefaultBufferCount(),
87b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            getIdentity());
8896f0819f81293076e652792794a961543e6750d7Mathias Agopian
89579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
90dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    sp<UserClient> ourClient(mUserClientRef.getClient());
91dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
92dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    /*
93dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  Here it is guaranteed that userClient != ourClient
94dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  (see UserClient::getTokenForSurface()).
95dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
96dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  We release the token used by this surface in ourClient below.
97dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  This should be safe to do so now, since this layer won't be attached
98dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  to this client, it should be okay to reuse that id.
99dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
100dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  If this causes problems, an other solution would be to keep a list
101dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  of all the {UserClient, token} ever used and release them when the
102dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  Layer is destroyed.
103dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
104dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     */
105dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
106dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    if (ourClient != 0) {
107dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian        ourClient->detachLayer(this);
108dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    }
109dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
110dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
111579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    LOGE_IF(err != NO_ERROR,
112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            "ClientRef::setToken(%p, %p, %u) failed",
113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            userClient.get(), lcblk.get(), token);
114579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
115579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if (err == NO_ERROR) {
116579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        // we need to free the buffers associated with this surface
117b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
11896f0819f81293076e652792794a961543e6750d7Mathias Agopian
119b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return err;
120b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
12196f0819f81293076e652792794a961543e6750d7Mathias Agopian
122b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::getToken() const
123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
124b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mUserClientRef.getToken();
12596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
12696f0819f81293076e652792794a961543e6750d7Mathias Agopian
127579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::getClient() const
128579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
129579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return mUserClientRef.getClient();
130579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
131579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
132d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
133d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
134d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
135d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lcblk) {
13996f0819f81293076e652792794a961543e6750d7Mathias Agopian        // wake up the condition
14096f0819f81293076e652792794a961543e6750d7Mathias Agopian        lcblk->setStatus(NO_INIT);
14196f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
14248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
143cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
144076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
146a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
147a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
1519a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
152bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: Called from the main UI thread
153bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
155f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
156bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
157bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
158bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mWidth = mHeight = 0;
1599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
162f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
165401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
170401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
171401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
172ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
173ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
181401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
182401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
183a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
184a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
185cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
186ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
187cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
188eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
189eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqFormat = format;
190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqWidth = w;
191eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqHeight = h;
192eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1933330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
19416f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
1953b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
1963b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy            (flags & ISurfaceComposer::eOpaque) == 0;
197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
198401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
199401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
200401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
201401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
202401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
206a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setGeometry(hwc_layer_t* hwcl)
207a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
208a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->compositionType = HWC_FRAMEBUFFER;
209a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->hints = 0;
210a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->flags = 0;
211a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->transform = 0;
212a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->blending = HWC_BLENDING_NONE;
213a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
214a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
215a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
216a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
218a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
219a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
220a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
221a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
222a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (mOrientation & Transform::ROT_INVALID) {
223a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
225a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
226a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
22786bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
22886bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    hwcl->transform = tr.getOrientation();
229a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
230a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (needsBlending()) {
231a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->blending = mPremultipliedAlpha ?
232a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
233a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
234a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
235a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.left   = mTransformedBounds.left;
236a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.top    = mTransformedBounds.top;
237a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.right  = mTransformedBounds.right;
238a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
239a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
240a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->visibleRegionScreen.rects =
241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            reinterpret_cast<hwc_rect_t const *>(
242a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                    visibleRegionScreen.getArray(
243a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                            &hwcl->visibleRegionScreen.numRects));
244a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
245a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
246a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setPerFrameData(hwc_layer_t* hwcl) {
247a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (buffer == NULL) {
249da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // this can happen if the client never drew into this layer yet,
250da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // or if we ran out of memory. In that case, don't let
251da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // HWC handle it.
252da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        hwcl->flags |= HWC_SKIP_LAYER;
253a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->handle = NULL;
254a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
255a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
256040481419473cb9913b632cd8973b1d7065f9c9cLouis Huemiller    hwcl->handle = buffer->handle;
257f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian
258f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    if (!mBufferCrop.isEmpty()) {
259f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = mBufferCrop.left;
260f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = mBufferCrop.top;
261f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = mBufferCrop.right;
262f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
263f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    } else {
264f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = 0;
265f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = 0;
266f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = buffer->width;
267f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = buffer->height;
268f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    }
269a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
270a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
273d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
2748f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
2758f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
2768f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
2778f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
2788f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
2798f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
2808f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
2811f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    if (mGLExtensions.haveDirectTexture()) {
282d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
283d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
284d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            // not sure what we can do here...
285d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            goto slowpath;
286076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
2871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    } else {
288fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
290f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
291f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
292f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
293f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                    res, strerror(res), buffer.get());
294f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            if (res == NO_ERROR) {
295f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                mBufferManager.loadTexture(dirty, t);
296f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                buffer->unlock();
297f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            }
298f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        } else {
299f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            // we can't do anything
300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianvoid Layer::drawForSreenShot() const
30574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
306733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const bool currentFiltering = mNeedsFiltering;
307733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = true;
30874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    LayerBase::drawForSreenShot();
309733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
31074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
31174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
314d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Texture tex(mBufferManager.getActiveTexture());
315d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (tex.name == -1LU) {
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
319179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            clearWithOpenGL(holes, 0, 0, 0, 1);
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
341d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    drawWithOpenGL(clip, tex);
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
344ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
345ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
346ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
347ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
348ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
349ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
350ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
351ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const
352ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
353ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // If buffers where set with eOpaque flag, all buffers are known to
354ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // be opaque without having to check their actual format
355ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    if (mNeedsBlending && buffer != NULL) {
356ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        PixelFormat format = buffer->getPixelFormat();
357ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
358ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (HARDWARE_IS_DEVICE_FORMAT(format)) {
359ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            return false;
360ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
361ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
362ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        PixelFormatInfo info;
363ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        status_t err = getPixelFormatInfo(format, &info);
364ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (!err && info.h_alpha <= info.l_alpha) {
365ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            return false;
366ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
367ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
368ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
369ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // Return opacity as determined from flags and format options
370ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // passed to setBuffers()
371ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    return mNeedsBlending;
372ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
373ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
374ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending() const
375ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
376ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    if (mBufferManager.hasActiveBuffer()) {
377ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        return needsBlending(mBufferManager.getActiveBuffer());
378ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
379ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
380ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    return mNeedsBlending;
381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
382ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
383a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const
384a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
385a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
386733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // if our buffer is not the same size than ourselves,
387733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // we need filtering.
388733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        Mutex::Autolock _l(mLock);
389733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        if (mNeedsScaling)
390a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian            return true;
391a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    }
392a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    return LayerBase::needsFiltering();
393a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
394a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
3957a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
3967a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
3977a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer());
3987a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
3997a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4007a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
401b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
402b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
403b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
406b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
407b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        // oops, the client is already gone
408b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        return DEAD_OBJECT;
409b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
410b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = lcblk->resize(bufferCount);
41354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (err == NO_ERROR) {
41454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
41554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferManager.resize(bufferCount, mFlinger, dpy);
41654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
417b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
418b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
419b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
420b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
421a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
422a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t usage)
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4253330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
42648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
429a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
431a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
432a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
43348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
43448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
43848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
43948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
44048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
44148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
443cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
44748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
448208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    status_t err = NO_ERROR;
449a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, f;
45048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
45148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
452eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
453eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        // zero means default
454e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian        const bool fixedSize = reqWidth && reqHeight;
455eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqFormat) reqFormat = mFormat;
456eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqWidth)  reqWidth = mWidth;
457eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqHeight) reqHeight = mHeight;
458eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
459eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        w = reqWidth;
460eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        h = reqHeight;
461eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        f = reqFormat;
462eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
463eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
464eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian                (reqFormat != mReqFormat)) {
465eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqWidth  = reqWidth;
466eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqHeight = reqHeight;
467eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqFormat = reqFormat;
468e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian            mFixedSize = fixedSize;
469733189d408e13b54fd70971b265244367efd0f51Mathias Agopian            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
470eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
471a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAllExcept(index);
472a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
47348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
47448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
475208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // here we have to reallocate a new buffer because the buffer could be
476208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // used as the front buffer, or by a client in our process
477208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // (eg: status bar), and we can't release the handle under its feet.
4783330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
479208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
480208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    err = buffer->initCheck();
481cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
482cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
483678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian        GraphicBuffer::dumpAllocationsToSystemLog();
484cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
485cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
486cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
488cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
4897e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
4907e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
493cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
49448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
495a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
496f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
497cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
498f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
499f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
5003330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
5013330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
5023330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
5033330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
5043330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
5053330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5063330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
5073330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
5083330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5093330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
5103330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
5113330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5123330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
5133330b203039dea366d4981db1408a460134b2d2cMathias Agopian
5143330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
5153330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
5163330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
5173330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
5183330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
5193330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
5203330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
52189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        // request EGLImage for all buffers
52289141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
5233330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
5247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    if (mProtectedByApp) {
52516f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        // need a hardware-protected path to external video sink
52616f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        usage |= GraphicBuffer::USAGE_PROTECTED;
52716f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    }
5283330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
5293330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
5303330b203039dea366d4981db1408a460134b2d2cMathias Agopian
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
537a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            (front.requested_h != temp.requested_h);
538a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
539a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
540cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
542a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
543a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                this,
544a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
545a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(front.requested_w), int(front.requested_h));
546a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
547a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
548a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // we're being resized and there is a freeze display request,
549a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // acquire a freeze lock, so that the screen stays put
550a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // until we've redrawn at the new size; this is to avoid
551a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // glitches upon orientation changes.
552a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
553a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // if the surface is hidden, don't try to acquire the
554a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
555a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
556a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                }
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
559caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // the drawing state's size
562a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            Layer::State& editDraw(mDrawingState);
563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_w = temp.requested_w;
564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_h = temp.requested_h;
565df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
566a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size, form this point on, when the client request
567a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // a buffer, it'll get the new size.
568a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
5696656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            ClientRef::Access sharedClient(mUserClientRef);
571b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            SharedBufferServer* lcblk(sharedClient.get());
572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (lcblk) {
57396f0819f81293076e652792794a961543e6750d7Mathias Agopian                // all buffers need reallocation
57496f0819f81293076e652792794a961543e6750d7Mathias Agopian                lcblk->reallocateAll();
57596f0819f81293076e652792794a961543e6750d7Mathias Agopian            }
576a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        } else {
577a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size
578a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
579a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
581cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
593a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
594cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
595cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
596cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
597733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
600a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const {
601a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mLock);
602a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mFixedSize;
603a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
604a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
611b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
612b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
613b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
61496f0819f81293076e652792794a961543e6750d7Mathias Agopian        // client died
61596f0819f81293076e652792794a961543e6750d7Mathias Agopian        recomputeVisibleRegions = true;
61696f0819f81293076e652792794a961543e6750d7Mathias Agopian        return;
61796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
61896f0819f81293076e652792794a961543e6750d7Mathias Agopian
619cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf == NOT_ENOUGH_DATA) {
621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // retire. The buffer is locked because we will use it
623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
626d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf < NO_ERROR) {
628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
629d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
630d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
631d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
632d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
634da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
635da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
636ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    const bool activeBlending =
637ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer());
638ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
639d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
640b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
641d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mPostedDirtyRegion.clear();
642d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        return;
643d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
645da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    if (noActiveBuffer) {
646da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // we didn't have an active buffer, we need to recompute
647da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // our visible region
648da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        recomputeVisibleRegions = true;
649da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    }
650da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6513330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
652d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
653ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) {
654ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            // new buffer has different opacity than previous active buffer, need
655ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            // to recompute visible regions accordingly
656ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            recomputeVisibleRegions = true;
657ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
658ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
659b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the dirty region
660d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
661d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
662d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
663d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
664d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
665d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
666d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
667d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
668df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
669d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
670d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
671d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
672d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
673d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
674d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
675d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
676d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
677d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
678d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
679d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
680d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
681d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
682d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
683d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
684d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
685d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
686d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
687d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
688d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
689d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
690d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
6918f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
692d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
693d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
694d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
695b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
696b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the crop region
697b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferCrop( lcblk->getCrop(buf) );
698b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
699b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the transformation
700b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferTransform( lcblk->getTransform(buf) );
701b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
702d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
703d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
704d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
705d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
706d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
707d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
708caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
709caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
710e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
711e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
712e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
713e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
715245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
716245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
717245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
718245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
719245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
720245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
721245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
722245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
723245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
745c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
746c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
7471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
748c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
749c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
757b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
758b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    uint32_t totalTime = 0;
759b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lcblk) {
760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        SharedBufferStack::Statistics stats = lcblk->getStats();
761b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        totalTime= stats.totalTime;
762b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        result.append( lcblk->dump("      ") );
763b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
764b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
7651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
7661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
7671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
7681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
7691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
7731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
7751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
7761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
7771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
7781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
7811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
7821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mFormat, w0, h0, s0, w1, h1, s1,
784b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            getFreezeLock().get(), totalTime);
7851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
7871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
7881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
789076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
790076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::ClientRef()
792579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0), mToken(-1) {
793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
794b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
795b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::~ClientRef() {
796b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
798b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::ClientRef::getToken() const {
799b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
800b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mToken;
801b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
802b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
803579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const {
804579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    Mutex::Autolock _l(mLock);
805579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return mUserClient.promote();
806579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
807579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
808b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
809579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        const sp<SharedBufferServer>& sharedClient, int32_t token) {
810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
811579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
812579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    { // scope for strong mUserClient reference
813579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        sp<UserClient> userClient(mUserClient.promote());
814579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if (mUserClient != 0 && mControlBlock != 0) {
815579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            mControlBlock->setStatus(NO_INIT);
816579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
817579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    }
818579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
819b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClient = uc;
820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mToken = token;
821579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    mControlBlock = sharedClient;
822b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
823b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
824b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
825b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
826b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mUserClient.promote();
827b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
828b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
829b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// this class gives us access to SharedBufferServer safely
830b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// it makes sure the UserClient (and its associated shared memory)
831b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// won't go away while we're accessing it.
832b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref)
833579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0)
834b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
835b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(ref.mLock);
836b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClientStrongRef = ref.mUserClient.promote();
837b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (mUserClientStrongRef != 0)
838579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        mControlBlock = ref.mControlBlock;
839579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
840579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
841579b3f88d03d06b897b778bd11818f5104677d1dMathias AgopianLayer::ClientRef::Access::~Access()
842579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
843b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
844b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
845b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
846b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
847d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
848bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
849420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian      mActiveBufferIndex(-1), mFailover(false)
850bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
851bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
852bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
853bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager()
854d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
855d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
856d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
85754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennisstatus_t Layer::BufferManager::resize(size_t size,
85854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
859bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
860bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
86154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
86254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (size < mNumBuffers) {
86354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Move the active texture into slot 0
864420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        BufferData activeBufferData = mBufferData[mActiveBufferIndex];
865420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mBufferData[mActiveBufferIndex] = mBufferData[0];
86654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferData[0] = activeBufferData;
867420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mActiveBufferIndex = 0;
86854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
86954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Free the buffers that are no longer needed.
87054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        for (size_t i = size; i < mNumBuffers; i++) {
87154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].buffer = 0;
87254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
87354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Create a message to destroy the textures on SurfaceFlinger's GL
87454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // thread.
87554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            class MessageDestroyTexture : public MessageBase {
87654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                Image mTexture;
87754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                EGLDisplay mDpy;
87854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis             public:
87954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
88054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    : mTexture(texture), mDpy(dpy) { }
88154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                virtual bool handler() {
88254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    status_t err = Layer::BufferManager::destroyTexture(
88354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            &mTexture, mDpy);
88454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
88554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            mTexture.name, strerror(-err));
88654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    return true; // XXX: err == 0;  ????
88754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                }
88854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            };
88954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
89054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            MessageDestroyTexture *msg = new MessageDestroyTexture(
89154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    mBufferData[i].texture, dpy);
89254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
89354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Don't allow this texture to be cleaned up by
89454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // BufferManager::destroy.
89554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.name = -1U;
89654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
89754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
89854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Post the message to the SurfaceFlinger object.
89954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            flinger->postMessageAsync(msg);
90054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        }
90154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
90254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
903bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mNumBuffers = size;
904bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
905d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
906d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
907d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging
908d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
909d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mBufferData[index].buffer;
910d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
911d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
912d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
913420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    BufferData const * const buffers = mBufferData;
914420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    Mutex::Autolock _l(mLock);
915420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBuffer = buffers[index].buffer;
916420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBufferIndex = index;
917d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
918d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
919d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
920d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
921420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex;
922d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
923d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
924d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
925bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Texture res;
926420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    if (mFailover || mActiveBufferIndex<0) {
927bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        res = mFailoverTexture;
928bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } else {
929420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture;
930bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
931bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
932d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
933d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
934d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
935420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBuffer;
936d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
937d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
938da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopianbool Layer::BufferManager::hasActiveBuffer() const {
939420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex >= 0;
940da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian}
941da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
942d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
943d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
944bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
945d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer;
946d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
947bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffer = buffers[index].buffer;
948bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = 0;
949d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return buffer;
950d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
951d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
952d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
953d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
954d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
955bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
956d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
957bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = buffer;
958bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].texture.dirty = true;
959d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
960d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
961d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
962d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
963d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
964bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
965bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    size_t num;
966bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    { // scope for the lock
967bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        Mutex::Autolock _l(mLock);
968bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        num = mNumBuffers;
969bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
970bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            buffers[i].buffer = 0;
971bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
972bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
973bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
974bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
975d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
976d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    destroyTexture(&mFailoverTexture, dpy);
977d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
978d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
979d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
980d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
981d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
982d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
983b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = NO_INIT;
984420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    ssize_t index = mActiveBufferIndex;
985b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (index >= 0) {
9861f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (!mFailover) {
9871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            Image& texture(mBufferData[index].texture);
9881f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = mTextureManager.initEglImage(&texture, dpy, buffer);
9891f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // if EGLImage fails, we switch to regular texture mode, and we
9901f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // free all resources associated with using EGLImages.
9911f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            if (err == NO_ERROR) {
9921f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = false;
9931f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                destroyTexture(&mFailoverTexture, dpy);
9941f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            } else {
9951f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = true;
9961f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                const size_t num = mNumBuffers;
9971f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                for (size_t i=0 ; i<num ; i++) {
9981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                    destroyTexture(&mBufferData[i].texture, dpy);
9991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                }
1000e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber            }
10011f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        } else {
10021f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // we failed once, don't try again
10031f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = BAD_VALUE;
1004d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        }
1005d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
1006d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return err;
1007d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1008d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1009d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture(
1010d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const Region& dirty, const GGLSurface& t)
1011d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
1012d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
1013d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1014d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1015bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
1016bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
1017bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->name != -1U) {
1018bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        glDeleteTextures(1, &tex->name);
1019bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->name = -1U;
1020bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1021bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
1022bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
1023bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
1024bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1025bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
1026bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
1027bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1028d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// ---------------------------------------------------------------------------
1029d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
10309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
103196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Layer>& owner)
103296f0819f81293076e652792794a961543e6750d7Mathias Agopian    : Surface(flinger, owner->getIdentity(), owner)
10339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
10369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
1037076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1038076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1039076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1040a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
1041a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
1042076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
10433330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
1044076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
1045076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
1046bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
1047bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * requestBuffer() cannot be called from the main thread
1048bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
1049bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1050bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1051a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
1052076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1053076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
1054076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1056b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
1057b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
1058b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    status_t err = DEAD_OBJECT;
1059b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Layer> owner(getOwner());
1060b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (owner != 0) {
1061bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
1062bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * setBufferCount() cannot be called from the main thread
1063bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
1064bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1065bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1066b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        err = owner->setBufferCount(bufferCount);
1067b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
1068b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
1069b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1070b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1075