Layer.cpp revision ac45e6bff1b41acd35c981291b37b23f8e083cee
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),
551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mGLExtensions(GLExtensions::getInstance()),
56401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        mNeedsBlending(true),
57d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mNeedsDithering(false),
58b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
5916f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        mProtectedByApp(false),
6016f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        mProtectedByDRM(false),
611f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mTextureManager(),
62a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager(mTextureManager),
63733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer()
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
69bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // FIXME: must be called from the main UI thread
70bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
71bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
72bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
73b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // we can use getUserClientUnsafe here because we know we're
74b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // single-threaded at that point.
75b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
76b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ourClient != 0) {
77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ourClient->detachLayer(this);
78b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
81b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::setToken(const sp<UserClient>& userClient,
82b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        SharedClient* sharedClient, int32_t token)
8396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
84579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    sp<SharedBufferServer> lcblk = new SharedBufferServer(
85b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            sharedClient, token, mBufferManager.getDefaultBufferCount(),
86b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            getIdentity());
8796f0819f81293076e652792794a961543e6750d7Mathias Agopian
88579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
89dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    sp<UserClient> ourClient(mUserClientRef.getClient());
90dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
91dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    /*
92dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  Here it is guaranteed that userClient != ourClient
93dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  (see UserClient::getTokenForSurface()).
94dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
95dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  We release the token used by this surface in ourClient below.
96dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  This should be safe to do so now, since this layer won't be attached
97dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  to this client, it should be okay to reuse that id.
98dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
99dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  If this causes problems, an other solution would be to keep a list
100dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  of all the {UserClient, token} ever used and release them when the
101dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *  Layer is destroyed.
102dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     *
103dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian     */
104dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
105dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    if (ourClient != 0) {
106dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian        ourClient->detachLayer(this);
107dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    }
108dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian
109dd17b3eaa99f761e265ff457e335b5a0ff83dafbMathias Agopian    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
110579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    LOGE_IF(err != NO_ERROR,
111579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            "ClientRef::setToken(%p, %p, %u) failed",
112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            userClient.get(), lcblk.get(), token);
113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
114579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if (err == NO_ERROR) {
115579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        // we need to free the buffers associated with this surface
116b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
11796f0819f81293076e652792794a961543e6750d7Mathias Agopian
118b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return err;
119b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
12096f0819f81293076e652792794a961543e6750d7Mathias Agopian
121b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::getToken() const
122b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mUserClientRef.getToken();
12496f0819f81293076e652792794a961543e6750d7Mathias Agopian}
12596f0819f81293076e652792794a961543e6750d7Mathias Agopian
126579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::getClient() const
127579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
128579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return mUserClientRef.getClient();
129579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
130579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
131d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
132d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
133d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
134d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
135b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lcblk) {
13896f0819f81293076e652792794a961543e6750d7Mathias Agopian        // wake up the condition
13996f0819f81293076e652792794a961543e6750d7Mathias Agopian        lcblk->setStatus(NO_INIT);
14096f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
14148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> Layer::createSurface() const
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSurface;
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t Layer::ditch()
1499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
150bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: Called from the main UI thread
151bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    // the layer is not on screen anymore. free as much resources as possible
153f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian    mFreezeLock.clear();
154bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1553cc2677efc2a4bc06297b9667ac529284f6abf9dMathias Agopian    // Free our own reference to ISurface
156bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mSurface.clear();
157bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
158bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
159bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mWidth = mHeight = 0;
1609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
163f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
166401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
172401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
173ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
181ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
182401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
183401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
184a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
185a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
186cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
187ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
188cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
189eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqFormat = format;
191eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqWidth = w;
192eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqHeight = h;
193eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1943330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
19516f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
19616f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false;
1973b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
1983b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy            (flags & ISurfaceComposer::eOpaque) == 0;
199ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
200401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
201401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
202401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
203401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
204401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
20596f0819f81293076e652792794a961543e6750d7Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, this);
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
209a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setGeometry(hwc_layer_t* hwcl)
210a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
211a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->compositionType = HWC_FRAMEBUFFER;
212a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->hints = 0;
213a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->flags = 0;
214a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->transform = 0;
215a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->blending = HWC_BLENDING_NONE;
216a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
218a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
219a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
220a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
221a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
222a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
223a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
225a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (mOrientation & Transform::ROT_INVALID) {
226a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
227a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
228a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
229a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
23086bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
23186bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    hwcl->transform = tr.getOrientation();
232a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
233a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (needsBlending()) {
234a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->blending = mPremultipliedAlpha ?
235a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
236a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
237a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
238a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.left   = mTransformedBounds.left;
239a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.top    = mTransformedBounds.top;
240a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.right  = mTransformedBounds.right;
241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
242a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
243a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->visibleRegionScreen.rects =
244a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            reinterpret_cast<hwc_rect_t const *>(
245a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                    visibleRegionScreen.getArray(
246a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                            &hwcl->visibleRegionScreen.numRects));
247a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
249a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setPerFrameData(hwc_layer_t* hwcl) {
250a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
251a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (buffer == NULL) {
252da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // this can happen if the client never drew into this layer yet,
253da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // or if we ran out of memory. In that case, don't let
254da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // HWC handle it.
255da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        hwcl->flags |= HWC_SKIP_LAYER;
256a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->handle = NULL;
257a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
258a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
259040481419473cb9913b632cd8973b1d7065f9c9cLouis Huemiller    hwcl->handle = buffer->handle;
260f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian
261f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    if (!mBufferCrop.isEmpty()) {
262f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = mBufferCrop.left;
263f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = mBufferCrop.top;
264f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = mBufferCrop.right;
265f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
266f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    } else {
267f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = 0;
268f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = 0;
269f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = buffer->width;
270f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = buffer->height;
271f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    }
272a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
273a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
276d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
2778f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
2788f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
2798f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
2808f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
2818f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
2828f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
2838f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
2841f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    if (mGLExtensions.haveDirectTexture()) {
285d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
286d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
287d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            // not sure what we can do here...
288d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            goto slowpath;
289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
2901f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    } else {
291fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
292076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
293f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
294f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
295f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
296f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                    res, strerror(res), buffer.get());
297f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            if (res == NO_ERROR) {
298f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                mBufferManager.loadTexture(dirty, t);
299f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                buffer->unlock();
300f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            }
301f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        } else {
302f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            // we can't do anything
303076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianvoid Layer::drawForSreenShot() const
30874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
309733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const bool currentFiltering = mNeedsFiltering;
310733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = true;
31174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    LayerBase::drawForSreenShot();
312733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
31374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
31474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
317d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Texture tex(mBufferManager.getActiveTexture());
318d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (tex.name == -1LU) {
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            clearWithOpenGL(holes, 0, 0, 0, 1);
341179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
344d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    drawWithOpenGL(clip, tex);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
347ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
348ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
349ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
350ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
351ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
352ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
353ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
354ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const
355ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
356ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // If buffers where set with eOpaque flag, all buffers are known to
357ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // be opaque without having to check their actual format
358ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    if (mNeedsBlending && buffer != NULL) {
359ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        PixelFormat format = buffer->getPixelFormat();
360ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
361ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (HARDWARE_IS_DEVICE_FORMAT(format)) {
362ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            return false;
363ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
364ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
365ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        PixelFormatInfo info;
366ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        status_t err = getPixelFormatInfo(format, &info);
367ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (!err && info.h_alpha <= info.l_alpha) {
368ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            return false;
369ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
370ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
371ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
372ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // Return opacity as determined from flags and format options
373ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    // passed to setBuffers()
374ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    return mNeedsBlending;
375ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
376ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
377ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassoldbool Layer::needsBlending() const
378ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
379ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    if (mBufferManager.hasActiveBuffer()) {
380ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        return needsBlending(mBufferManager.getActiveBuffer());
381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
382ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
383ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    return mNeedsBlending;
384ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
385ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
386a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const
387a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
388a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
389733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // if our buffer is not the same size than ourselves,
390733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // we need filtering.
391733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        Mutex::Autolock _l(mLock);
392733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        if (mNeedsScaling)
393a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian            return true;
394a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    }
395a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    return LayerBase::needsFiltering();
396a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
397a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
398b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
399b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
400b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
401b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
404b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        // oops, the client is already gone
405b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        return DEAD_OBJECT;
406b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
407b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
409bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = lcblk->resize(bufferCount);
41054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (err == NO_ERROR) {
41154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
41254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferManager.resize(bufferCount, mFlinger, dpy);
41354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
414b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
415b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
416b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
417b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
418a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
419a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
420a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t usage)
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4223330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
42348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
425a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
426a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
427a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
429a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
43048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
43148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
432b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
433b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
434b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
43548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
43648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
43748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
43848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
440cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
441cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
442cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
44448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
445208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    status_t err = NO_ERROR;
446a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, f;
44748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
44848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
449eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
450eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        // zero means default
451e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian        const bool fixedSize = reqWidth && reqHeight;
452eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqFormat) reqFormat = mFormat;
453eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqWidth)  reqWidth = mWidth;
454eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqHeight) reqHeight = mHeight;
455eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
456eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        w = reqWidth;
457eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        h = reqHeight;
458eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        f = reqFormat;
459eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
460eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
461eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian                (reqFormat != mReqFormat)) {
462eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqWidth  = reqWidth;
463eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqHeight = reqHeight;
464eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqFormat = reqFormat;
465e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian            mFixedSize = fixedSize;
466733189d408e13b54fd70971b265244367efd0f51Mathias Agopian            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
467eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
468a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAllExcept(index);
469a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
47048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
47148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
472208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // here we have to reallocate a new buffer because the buffer could be
473208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // used as the front buffer, or by a client in our process
474208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // (eg: status bar), and we can't release the handle under its feet.
4753330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
476208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
477208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    err = buffer->initCheck();
478cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
479cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
480678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian        GraphicBuffer::dumpAllocationsToSystemLog();
481cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
482cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
483cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
485cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
4867e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
4877e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
49148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
492a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
493f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
494cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
495f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
496f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
4973330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
4983330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
4993330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
5003330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
5013330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
5023330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5033330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
5043330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
5053330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5063330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
5073330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
5083330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
5093330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
5103330b203039dea366d4981db1408a460134b2d2cMathias Agopian
5113330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
5123330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
5133330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
5143330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
5153330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
5163330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
5173330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
51889141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        // request EGLImage for all buffers
51989141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
5203330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
52116f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    if (mProtectedByApp || mProtectedByDRM) {
52216f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        // need a hardware-protected path to external video sink
52316f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        usage |= GraphicBuffer::USAGE_PROTECTED;
52416f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    }
5253330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
5263330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
5273330b203039dea366d4981db1408a460134b2d2cMathias Agopian
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
533a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
534a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            (front.requested_h != temp.requested_h);
535a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
537cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
539a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
540a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                this,
541a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
542a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(front.requested_w), int(front.requested_h));
543a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
544a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
545a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // we're being resized and there is a freeze display request,
546a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // acquire a freeze lock, so that the screen stays put
547a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // until we've redrawn at the new size; this is to avoid
548a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // glitches upon orientation changes.
549a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
550a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // if the surface is hidden, don't try to acquire the
551a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
552a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
553a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
554a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                }
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
556caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
558a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // the drawing state's size
559a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            Layer::State& editDraw(mDrawingState);
560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_w = temp.requested_w;
561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_h = temp.requested_h;
562df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size, form this point on, when the client request
564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // a buffer, it'll get the new size.
565a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
5666656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
567b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            ClientRef::Access sharedClient(mUserClientRef);
568b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            SharedBufferServer* lcblk(sharedClient.get());
569b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (lcblk) {
57096f0819f81293076e652792794a961543e6750d7Mathias Agopian                // all buffers need reallocation
57196f0819f81293076e652792794a961543e6750d7Mathias Agopian                lcblk->reallocateAll();
57296f0819f81293076e652792794a961543e6750d7Mathias Agopian            }
573a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        } else {
574a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size
575a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
576a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
590a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
591cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
592cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
593cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
594733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
597a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const {
598a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mLock);
599a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mFixedSize;
600a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
601a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
608b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
609b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
610b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
61196f0819f81293076e652792794a961543e6750d7Mathias Agopian        // client died
61296f0819f81293076e652792794a961543e6750d7Mathias Agopian        recomputeVisibleRegions = true;
61396f0819f81293076e652792794a961543e6750d7Mathias Agopian        return;
61496f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
61596f0819f81293076e652792794a961543e6750d7Mathias Agopian
616cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
617d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf == NOT_ENOUGH_DATA) {
618d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
619d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // retire. The buffer is locked because we will use it
620cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
623d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
624d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf < NO_ERROR) {
625b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
626d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
627d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
628d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
629d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
630cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
631da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
632da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
633ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    const bool activeBlending =
634ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer());
635ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
637b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
638d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mPostedDirtyRegion.clear();
639d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        return;
640d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
642da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    if (noActiveBuffer) {
643da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // we didn't have an active buffer, we need to recompute
644da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // our visible region
645da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        recomputeVisibleRegions = true;
646da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    }
647da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6483330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
649d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
650ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) {
651ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            // new buffer has different opacity than previous active buffer, need
652ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            // to recompute visible regions accordingly
653ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold            recomputeVisibleRegions = true;
654ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
655ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
656b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the dirty region
657d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
658d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
659d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
660d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
661d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
662d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
663d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
664d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
665df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
666d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
667d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
668d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
669d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
670d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
671d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
672d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
673d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
674d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
675d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
676d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
677d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
678d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
679d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
680d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
681d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
682d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
683d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
684d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
685d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
686d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
687d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
6888f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
689d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
690d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
691d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
692b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
693b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the crop region
694b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferCrop( lcblk->getCrop(buf) );
695b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
696b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the transformation
697b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferTransform( lcblk->getTransform(buf) );
698b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
699d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
700d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
701d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
702d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
703d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
704d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
705caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
706caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
707e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
708e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
709e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
710e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
712245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
713245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
714245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
715245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
716245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
717245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
718245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
719245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
720245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
742c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
743c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
7441b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
745c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
746c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
753b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
754b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
755b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    uint32_t totalTime = 0;
756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lcblk) {
757b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        SharedBufferStack::Statistics stats = lcblk->getStats();
758b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        totalTime= stats.totalTime;
759b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        result.append( lcblk->dump("      ") );
760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
761b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
7621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
7631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
7641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
7651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
7661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
7701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
7721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
7731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
7741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
7751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
7781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
7791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mFormat, w0, h0, s0, w1, h1, s1,
781b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            getFreezeLock().get(), totalTime);
7821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
7841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
7851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
786076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
787076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
788b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::ClientRef()
789579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0), mToken(-1) {
790b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
792b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::~ClientRef() {
793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
794b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
795b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::ClientRef::getToken() const {
796b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mToken;
798b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
799b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
800579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const {
801579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    Mutex::Autolock _l(mLock);
802579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return mUserClient.promote();
803579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
804579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
805b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
806579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        const sp<SharedBufferServer>& sharedClient, int32_t token) {
807b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
808579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
809579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    { // scope for strong mUserClient reference
810579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        sp<UserClient> userClient(mUserClient.promote());
811579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if (mUserClient != 0 && mControlBlock != 0) {
812579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            mControlBlock->setStatus(NO_INIT);
813579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
814579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    }
815579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
816b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClient = uc;
817b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mToken = token;
818579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    mControlBlock = sharedClient;
819b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
821b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
822b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
823b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mUserClient.promote();
824b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
825b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
826b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// this class gives us access to SharedBufferServer safely
827b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// it makes sure the UserClient (and its associated shared memory)
828b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// won't go away while we're accessing it.
829b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref)
830579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0)
831b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
832b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(ref.mLock);
833b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClientStrongRef = ref.mUserClient.promote();
834b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (mUserClientStrongRef != 0)
835579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        mControlBlock = ref.mControlBlock;
836579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
837579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
838579b3f88d03d06b897b778bd11818f5104677d1dMathias AgopianLayer::ClientRef::Access::~Access()
839579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
840b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
841b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
842b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
843b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
844d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
845bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
846420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian      mActiveBufferIndex(-1), mFailover(false)
847bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
848bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
849bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
850bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager()
851d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
852d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
853d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
85454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennisstatus_t Layer::BufferManager::resize(size_t size,
85554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
856bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
857bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
85854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
85954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (size < mNumBuffers) {
86054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Move the active texture into slot 0
861420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        BufferData activeBufferData = mBufferData[mActiveBufferIndex];
862420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mBufferData[mActiveBufferIndex] = mBufferData[0];
86354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferData[0] = activeBufferData;
864420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mActiveBufferIndex = 0;
86554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
86654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Free the buffers that are no longer needed.
86754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        for (size_t i = size; i < mNumBuffers; i++) {
86854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].buffer = 0;
86954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
87054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Create a message to destroy the textures on SurfaceFlinger's GL
87154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // thread.
87254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            class MessageDestroyTexture : public MessageBase {
87354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                Image mTexture;
87454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                EGLDisplay mDpy;
87554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis             public:
87654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
87754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    : mTexture(texture), mDpy(dpy) { }
87854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                virtual bool handler() {
87954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    status_t err = Layer::BufferManager::destroyTexture(
88054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            &mTexture, mDpy);
88154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
88254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            mTexture.name, strerror(-err));
88354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    return true; // XXX: err == 0;  ????
88454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                }
88554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            };
88654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
88754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            MessageDestroyTexture *msg = new MessageDestroyTexture(
88854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    mBufferData[i].texture, dpy);
88954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
89054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Don't allow this texture to be cleaned up by
89154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // BufferManager::destroy.
89254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.name = -1U;
89354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
89454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
89554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Post the message to the SurfaceFlinger object.
89654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            flinger->postMessageAsync(msg);
89754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        }
89854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
89954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
900bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mNumBuffers = size;
901bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
902d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
903d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
904d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging
905d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
906d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mBufferData[index].buffer;
907d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
908d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
909d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
910420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    BufferData const * const buffers = mBufferData;
911420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    Mutex::Autolock _l(mLock);
912420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBuffer = buffers[index].buffer;
913420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBufferIndex = index;
914d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
915d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
916d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
917d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
918420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex;
919d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
920d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
921d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
922bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Texture res;
923420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    if (mFailover || mActiveBufferIndex<0) {
924bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        res = mFailoverTexture;
925bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } else {
926420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture;
927bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
928bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
929d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
930d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
931d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
932420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBuffer;
933d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
934d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
935da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopianbool Layer::BufferManager::hasActiveBuffer() const {
936420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex >= 0;
937da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian}
938da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
939d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
940d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
941bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
942d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer;
943d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
944bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffer = buffers[index].buffer;
945bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = 0;
946d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return buffer;
947d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
948d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
949d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
950d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
951d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
952bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
953d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
954bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = buffer;
955bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].texture.dirty = true;
956d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
957d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
958d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
959d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
960d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
961bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
962bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    size_t num;
963bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    { // scope for the lock
964bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        Mutex::Autolock _l(mLock);
965bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        num = mNumBuffers;
966bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
967bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            buffers[i].buffer = 0;
968bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
969bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
970bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
971bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
972d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
973d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    destroyTexture(&mFailoverTexture, dpy);
974d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
975d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
976d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
977d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
978d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
979d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
980b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = NO_INIT;
981420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    ssize_t index = mActiveBufferIndex;
982b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (index >= 0) {
9831f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (!mFailover) {
9841f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            Image& texture(mBufferData[index].texture);
9851f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = mTextureManager.initEglImage(&texture, dpy, buffer);
9861f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // if EGLImage fails, we switch to regular texture mode, and we
9871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // free all resources associated with using EGLImages.
9881f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            if (err == NO_ERROR) {
9891f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = false;
9901f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                destroyTexture(&mFailoverTexture, dpy);
9911f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            } else {
9921f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = true;
9931f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                const size_t num = mNumBuffers;
9941f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                for (size_t i=0 ; i<num ; i++) {
9951f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                    destroyTexture(&mBufferData[i].texture, dpy);
9961f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                }
997e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber            }
9981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        } else {
9991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // we failed once, don't try again
10001f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = BAD_VALUE;
1001d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        }
1002d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
1003d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return err;
1004d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1005d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1006d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture(
1007d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const Region& dirty, const GGLSurface& t)
1008d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
1009d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
1010d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1011d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1012bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
1013bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
1014bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->name != -1U) {
1015bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        glDeleteTextures(1, &tex->name);
1016bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->name = -1U;
1017bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1018bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
1019bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
1020bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
1021bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1022bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
1023bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
1024bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1025d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// ---------------------------------------------------------------------------
1026d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
10279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
102896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Layer>& owner)
102996f0819f81293076e652792794a961543e6750d7Mathias Agopian    : Surface(flinger, owner->getIdentity(), owner)
10309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10329a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
10339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
1034076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1035076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1036076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1037a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
1038a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
1039076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
10403330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
1041076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
1042076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
1043bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
1044bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * requestBuffer() cannot be called from the main thread
1045bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
1046bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1047bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1048a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
1049076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1050076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
1051076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1053b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
1054b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
1055b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    status_t err = DEAD_OBJECT;
1056b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Layer> owner(getOwner());
1057b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (owner != 0) {
1058bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
1059bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * setBufferCount() cannot be called from the main thread
1060bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
1061bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1062bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1063b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        err = owner->setBufferCount(bufferCount);
1064b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
1065b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
1066b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1067b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1072