Layer.cpp revision 16f0453fee84c6aad59fe0d1c7d36f061d46cffc
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
155bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
156bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mBufferManager.destroy(dpy);
157bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mSurface.clear();
158bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
159bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
160bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mWidth = mHeight = 0;
1619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return NO_ERROR;
1629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
1639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
164f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
167401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) return err;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
173401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
181ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
182ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
183401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
184401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
185a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
186a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
187cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
188ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    mWidth  = w;
189cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
191eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqFormat = format;
192eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqWidth = w;
193eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian    mReqHeight = h;
194eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1953330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
19616f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
19716f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false;
1983b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
1993b996c96e4cd1057cb6b9531eaf8c01f934d2b2aRomain Guy            (flags & ISurfaceComposer::eOpaque) == 0;
200ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
201401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
202401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
203401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
204401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
205401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
20696f0819f81293076e652792794a961543e6750d7Mathias Agopian    mSurface = new SurfaceLayer(mFlinger, this);
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setGeometry(hwc_layer_t* hwcl)
211a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
212a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->compositionType = HWC_FRAMEBUFFER;
213a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->hints = 0;
214a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->flags = 0;
215a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->transform = 0;
216a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->blending = HWC_BLENDING_NONE;
217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
218a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
219a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
220a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
221a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
222a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
223a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
225a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
226a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (mOrientation & Transform::ROT_INVALID) {
227a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
228a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
229a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
230a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
23186bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
23286bdb2f918ffd238d6e0d1ae1f95af882f04d6cbMathias Agopian    hwcl->transform = tr.getOrientation();
233a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
234a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (needsBlending()) {
235a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->blending = mPremultipliedAlpha ?
236a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
237a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
238a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
239a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.left   = mTransformedBounds.left;
240a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.top    = mTransformedBounds.top;
241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.right  = mTransformedBounds.right;
242a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
243a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
244a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    hwcl->visibleRegionScreen.rects =
245a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            reinterpret_cast<hwc_rect_t const *>(
246a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                    visibleRegionScreen.getArray(
247a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian                            &hwcl->visibleRegionScreen.numRects));
248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
249a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
250a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setPerFrameData(hwc_layer_t* hwcl) {
251a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
252a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (buffer == NULL) {
253da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // this can happen if the client never drew into this layer yet,
254da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // or if we ran out of memory. In that case, don't let
255da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // HWC handle it.
256da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        hwcl->flags |= HWC_SKIP_LAYER;
257a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->handle = NULL;
258a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        return;
259a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
260040481419473cb9913b632cd8973b1d7065f9c9cLouis Huemiller    hwcl->handle = buffer->handle;
261f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian
262f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    if (!mBufferCrop.isEmpty()) {
263f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = mBufferCrop.left;
264f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = mBufferCrop.top;
265f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = mBufferCrop.right;
266f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
267f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    } else {
268f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.left   = 0;
269f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.top    = 0;
270f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.right  = buffer->width;
271f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian        hwcl->sourceCrop.bottom = buffer->height;
272f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian    }
273a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
274a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty)
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
277d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
2788f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    if (buffer == NULL) {
2798f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // this situation can happen if we ran out of memory for instance.
2808f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // not much we can do. continue to use whatever texture was bound
2818f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        // to this context.
2828f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian        return;
2838f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian    }
2848f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian
2851f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    if (mGLExtensions.haveDirectTexture()) {
286d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
287d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
288d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            // not sure what we can do here...
289d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian            goto slowpath;
290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
2911f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    } else {
292fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopianslowpath:
293076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        GGLSurface t;
294f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
295f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
296f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            LOGE_IF(res, "error %d (%s) locking buffer %p",
297f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                    res, strerror(res), buffer.get());
298f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            if (res == NO_ERROR) {
299f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                mBufferManager.loadTexture(dirty, t);
300f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian                buffer->unlock();
301f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            }
302f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian        } else {
303f1b38247d4d9c2ddc7315a72b609a95e0ed8050fMathias Agopian            // we can't do anything
304076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianvoid Layer::drawForSreenShot() const
30974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
310733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const bool currentFiltering = mNeedsFiltering;
311733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = true;
31274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    LayerBase::drawForSreenShot();
313733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
31474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
31574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
318d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Texture tex(mBufferManager.getActiveTexture());
319d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (tex.name == -1LU) {
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
340179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            clearWithOpenGL(holes, 0, 0, 0, 1);
342179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
345d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    drawWithOpenGL(clip, tex);
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopianbool Layer::needsFiltering() const
349a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
350a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
351733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // if our buffer is not the same size than ourselves,
352733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        // we need filtering.
353733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        Mutex::Autolock _l(mLock);
354733189d408e13b54fd70971b265244367efd0f51Mathias Agopian        if (mNeedsScaling)
355a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian            return true;
356a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    }
357a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian    return LayerBase::needsFiltering();
358a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
359a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
360b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
361b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::setBufferCount(int bufferCount)
362b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
363b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
364b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
365b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
366b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        // oops, the client is already gone
367b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        return DEAD_OBJECT;
368b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
369b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
370bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    // NOTE: lcblk->resize() is protected by an internal lock
371bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = lcblk->resize(bufferCount);
37254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (err == NO_ERROR) {
37354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
37454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferManager.resize(bufferCount, mFlinger, dpy);
37554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
376b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
377b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
378b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
379b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::requestBuffer(int index,
381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
382a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t usage)
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3843330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
38548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
386b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
389a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return buffer;
391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
39248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // this ensures our client doesn't go away while we're accessing
39348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    // the shared area.
394b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
395b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
396b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
39748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        // oops, the client is already gone
39848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        return buffer;
39948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
40048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
401076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    /*
402cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * This is called from the client's Surface::dequeue(). This can happen
403cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * at any time, especially while we're in the middle of using the
404cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian     * buffer 'index' as our front buffer.
405076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     */
40648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
407208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    status_t err = NO_ERROR;
408a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, f;
40948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    { // scope for the lock
41048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
411eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
412eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        // zero means default
413e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian        const bool fixedSize = reqWidth && reqHeight;
414eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqFormat) reqFormat = mFormat;
415eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqWidth)  reqWidth = mWidth;
416eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if (!reqHeight) reqHeight = mHeight;
417eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
418eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        w = reqWidth;
419eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        h = reqHeight;
420eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        f = reqFormat;
421eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
422eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
423eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian                (reqFormat != mReqFormat)) {
424eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqWidth  = reqWidth;
425eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqHeight = reqHeight;
426eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian            mReqFormat = reqFormat;
427e44d21a247aac5192b8ef397d433a4aefb6ba53eMathias Agopian            mFixedSize = fixedSize;
428733189d408e13b54fd70971b265244367efd0f51Mathias Agopian            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
429eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            lcblk->reallocateAllExcept(index);
431a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
43248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    }
43348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian
434208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // here we have to reallocate a new buffer because the buffer could be
435208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // used as the front buffer, or by a client in our process
436208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    // (eg: status bar), and we can't release the handle under its feet.
4373330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const uint32_t effectiveUsage = getEffectiveUsage(usage);
438208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
439208cb0772429b9ac800010829ecc7b854bdc2d24Mathias Agopian    err = buffer->initCheck();
440cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
441cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err || buffer->handle == 0) {
442678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian        GraphicBuffer::dumpAllocationsToSystemLog();
443cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err || buffer->handle == 0,
444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
445cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                this, index, w, h, strerror(-err));
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
447cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGD_IF(DEBUG_RESIZE,
4487e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
4497e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian                this, index, w, h, buffer->handle);
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR && buffer->handle != 0) {
45348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        Mutex::Autolock _l(mLock);
454a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferManager.attachBuffer(index, buffer);
455f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    }
456cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return buffer;
457f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian}
458f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian
4593330b203039dea366d4981db1408a460134b2d2cMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
4603330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
4613330b203039dea366d4981db1408a460134b2d2cMathias Agopian    /*
4623330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for software rendering, but h/w composition
4633330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
4643330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
4653330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used for h/w rendering and h/w composition
4663330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with  HW_RENDER | HW_TEXTURE
4673330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
4683330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
4693330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *  are allocated with SW_READ_RARELY | HW_RENDER
4703330b203039dea366d4981db1408a460134b2d2cMathias Agopian     *
4713330b203039dea366d4981db1408a460134b2d2cMathias Agopian     */
4723330b203039dea366d4981db1408a460134b2d2cMathias Agopian
4733330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (mSecure) {
4743330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // secure buffer, don't store it into the GPU
4753330b203039dea366d4981db1408a460134b2d2cMathias Agopian        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
4763330b203039dea366d4981db1408a460134b2d2cMathias Agopian                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
4773330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
4783330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // it's allowed to modify the usage flags here, but generally
4793330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // the requested flags should be honored.
48089141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        // request EGLImage for all buffers
48189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
4823330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
48316f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    if (mProtectedByApp || mProtectedByDRM) {
48416f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        // need a hardware-protected path to external video sink
48516f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten        usage |= GraphicBuffer::USAGE_PROTECTED;
48616f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    }
4873330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return usage;
4883330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
4893330b203039dea366d4981db1408a460134b2d2cMathias Agopian
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
495a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
496a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            (front.requested_h != temp.requested_h);
497a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
498a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
499cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGD_IF(DEBUG_RESIZE,
501a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
502a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                this,
503a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(temp.requested_w), int(temp.requested_h),
504a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                int(front.requested_w), int(front.requested_h));
505a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
506a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
507a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // we're being resized and there is a freeze display request,
508a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // acquire a freeze lock, so that the screen stays put
509a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // until we've redrawn at the new size; this is to avoid
510a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // glitches upon orientation changes.
511a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            if (mFlinger->hasFreezeRequest()) {
512a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // if the surface is hidden, don't try to acquire the
513a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                // freeze lock, since hidden surfaces may never redraw
514a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
515a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                    mFreezeLock = mFlinger->getFreezeLock();
516a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                }
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
518caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
519a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
520a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // the drawing state's size
521a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            Layer::State& editDraw(mDrawingState);
522a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_w = temp.requested_w;
523a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            editDraw.requested_h = temp.requested_h;
524df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian
525a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size, form this point on, when the client request
526a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // a buffer, it'll get the new size.
527a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
5286656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
529b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            ClientRef::Access sharedClient(mUserClientRef);
530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            SharedBufferServer* lcblk(sharedClient.get());
531b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (lcblk) {
53296f0819f81293076e652792794a961543e6750d7Mathias Agopian                // all buffers need reallocation
53396f0819f81293076e652792794a961543e6750d7Mathias Agopian                lcblk->reallocateAll();
53496f0819f81293076e652792794a961543e6750d7Mathias Agopian            }
535a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        } else {
536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // record the new size
537a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            setBufferSize(temp.requested_w, temp.requested_h);
538a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
540cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // this surface is now hidden, so it shouldn't hold a freeze lock
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // (it may never redraw, which is fine if it is hidden)
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeLock.clear();
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
552a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Layer::setBufferSize(uint32_t w, uint32_t h) {
553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mLock);
554cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mWidth = w;
555cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mHeight = h;
556733189d408e13b54fd70971b265244367efd0f51Mathias Agopian    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
559a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Layer::isFixedSize() const {
560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mLock);
561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mFixedSize;
562a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
571b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (!lcblk) {
57396f0819f81293076e652792794a961543e6750d7Mathias Agopian        // client died
57496f0819f81293076e652792794a961543e6750d7Mathias Agopian        recomputeVisibleRegions = true;
57596f0819f81293076e652792794a961543e6750d7Mathias Agopian        return;
57696f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
57796f0819f81293076e652792794a961543e6750d7Mathias Agopian
578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t buf = lcblk->retireAndLock();
579d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf == NOT_ENOUGH_DATA) {
580d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // NOTE: This is not an error, it simply means there is nothing to
581d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        // retire. The buffer is locked because we will use it
582cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // for composition later in the loop
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
585d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
586d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (buf < NO_ERROR) {
587b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
588d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
589d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        return;
590d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    }
591d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
592cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // we retired a buffer, which becomes the new front buffer
593da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
594da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
595d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
597d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mPostedDirtyRegion.clear();
598d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        return;
599d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    if (noActiveBuffer) {
602da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // we didn't have an active buffer, we need to recompute
603da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        // our visible region
604da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian        recomputeVisibleRegions = true;
605da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian    }
606da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6073330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
608d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    if (newFrontBuffer != NULL) {
609b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the dirty region
610d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // compute the posted region
611d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Region dirty(lcblk->getDirtyRegion(buf));
612d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
613d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
614d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // update the layer size and release freeze-lock
615d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
616d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        if (newFrontBuffer->getWidth()  == front.requested_w &&
617d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            newFrontBuffer->getHeight() == front.requested_h)
618df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian        {
619d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            if ((front.w != front.requested_w) ||
620d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                (front.h != front.requested_h))
621d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
622d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
623d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
624d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
625d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editDraw(mDrawingState);
626d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.w = editDraw.requested_w;
627d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editDraw.h = editDraw.requested_h;
628d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
629d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // We also need to update the current state so that we don't
630d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // end-up doing too much work during the next transaction.
631d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // NOTE: We actually don't need hold the transaction lock here
632d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // because State::w and State::h are only accessed from
633d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // this thread
634d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                Layer::State& editTemp(currentState());
635d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.w = editDraw.w;
636d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                editTemp.h = editDraw.h;
637d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
638d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
639d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
640d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            }
6418f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian
642d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            // we now have the correct size, unfreeze the screen
643d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            mFreezeLock.clear();
644d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
645b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
646b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the crop region
647b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferCrop( lcblk->getCrop(buf) );
648b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
649b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        // get the transformation
650b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        setBufferTransform( lcblk->getTransform(buf) );
651b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
652d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian    } else {
653d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // this should not happen unless we ran out of memory while
654d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // allocating the buffer. we're hoping that things will get back
655d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // to normal the next time the app tries to draw into this buffer.
656d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        // meanwhile, pretend the screen didn't update.
657d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        mPostedDirtyRegion.clear();
658caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian    }
659caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian
660e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    if (lcblk->getQueuedCount()) {
661e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        // signal an event if we have more buffers waiting
662e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian        mFlinger->signalEvent();
663e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
665245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    /* a buffer was posted, so we need to call reloadTexture(), which
666245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * will update our internal data structures (eg: EGLImageKHR or
667245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * texture names). we need to do this even if mPostedDirtyRegion is
668245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * empty -- it's orthogonal to the fact that a new buffer was posted,
669245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * for instance, a degenerate case could be that the user did an empty
670245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * update but repainted the buffer with appropriate content (after a
671245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     * resize for instance).
672245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian     */
673245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    reloadTexture( mPostedDirtyRegion );
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirtyRegion(mPostedDirtyRegion);
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!dirtyRegion.isEmpty()) {
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // The dirty region is given in the layer's coordinate space
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // transform the dirty region by the surface's transformation
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and the global transformation.
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Layer::State& s(drawingState());
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform tr(planeTransform * s.transform);
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion = tr.transform(dirtyRegion);
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // At this point, the dirty region is in screen space.
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Make sure it's constrained by the visible region (which
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // is in screen space as well).
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.andSelf(visibleRegionScreen);
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(dirtyRegion);
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
695c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    if (visibleRegionScreen.isEmpty()) {
696c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        // an invisible layer should not hold a freeze-lock
6971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        // (because it may never be updated and therefore never release it)
698c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian        mFreezeLock.clear();
699c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian    }
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
706b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ClientRef::Access sharedClient(mUserClientRef);
707b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedBufferServer* lcblk(sharedClient.get());
708b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    uint32_t totalTime = 0;
709b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lcblk) {
710b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        SharedBufferStack::Statistics stats = lcblk->getStats();
711b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        totalTime= stats.totalTime;
712b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        result.append( lcblk->dump("      ") );
713b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
714b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
7151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf0(getBuffer(0));
7161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    sp<const GraphicBuffer> buf1(getBuffer(1));
7171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w0=0, h0=0, s0=0;
7181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    uint32_t w1=0, h1=0, s1=0;
7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
7231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf1 != 0) {
7251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w1 = buf1->getWidth();
7261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h1 = buf1->getHeight();
7271b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s1 = buf1->getStride();
7281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
7311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
7321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            " freezeLock=%p, dq-q-time=%u us\n",
733b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mFormat, w0, h0, s0, w1, h1, s1,
734b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            getFreezeLock().get(), totalTime);
7351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
7371b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
7381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::ClientRef()
742579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0), mToken(-1) {
743b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
744b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
745b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::~ClientRef() {
746b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
747b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
748b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianint32_t Layer::ClientRef::getToken() const {
749b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
750b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mToken;
751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
753579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopiansp<UserClient> Layer::ClientRef::getClient() const {
754579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    Mutex::Autolock _l(mLock);
755579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return mUserClient.promote();
756579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
757579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
758b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
759579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        const sp<SharedBufferServer>& sharedClient, int32_t token) {
760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mLock);
761579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
762579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    { // scope for strong mUserClient reference
763579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        sp<UserClient> userClient(mUserClient.promote());
764579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if (mUserClient != 0 && mControlBlock != 0) {
765579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            mControlBlock->setStatus(NO_INIT);
766579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
767579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    }
768579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
769b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClient = uc;
770b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mToken = token;
771579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    mControlBlock = sharedClient;
772b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
773b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
774b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
775b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
776b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mUserClient.promote();
777b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
778b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
779b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// this class gives us access to SharedBufferServer safely
780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// it makes sure the UserClient (and its associated shared memory)
781b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// won't go away while we're accessing it.
782b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianLayer::ClientRef::Access::Access(const ClientRef& ref)
783579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    : mControlBlock(0)
784b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
785b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(ref.mLock);
786b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mUserClientStrongRef = ref.mUserClient.promote();
787b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (mUserClientStrongRef != 0)
788579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        mControlBlock = ref.mControlBlock;
789579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
790579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
791579b3f88d03d06b897b778bd11818f5104677d1dMathias AgopianLayer::ClientRef::Access::~Access()
792579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
794b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
795b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
796b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
797d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianLayer::BufferManager::BufferManager(TextureManager& tm)
798bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
799420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian      mActiveBufferIndex(-1), mFailover(false)
800bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
801bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
802bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
803bb641244d7d73312dc65b8e338df18b22e335107Mathias AgopianLayer::BufferManager::~BufferManager()
804d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
805d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
806d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
80754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennisstatus_t Layer::BufferManager::resize(size_t size,
80854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
809bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
810bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Mutex::Autolock _l(mLock);
81154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
81254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (size < mNumBuffers) {
81354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Move the active texture into slot 0
814420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        BufferData activeBufferData = mBufferData[mActiveBufferIndex];
815420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mBufferData[mActiveBufferIndex] = mBufferData[0];
81654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBufferData[0] = activeBufferData;
817420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        mActiveBufferIndex = 0;
81854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
81954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Free the buffers that are no longer needed.
82054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        for (size_t i = size; i < mNumBuffers; i++) {
82154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].buffer = 0;
82254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
82354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Create a message to destroy the textures on SurfaceFlinger's GL
82454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // thread.
82554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            class MessageDestroyTexture : public MessageBase {
82654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                Image mTexture;
82754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                EGLDisplay mDpy;
82854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis             public:
82954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
83054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    : mTexture(texture), mDpy(dpy) { }
83154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                virtual bool handler() {
83254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    status_t err = Layer::BufferManager::destroyTexture(
83354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            &mTexture, mDpy);
83454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
83554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                            mTexture.name, strerror(-err));
83654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    return true; // XXX: err == 0;  ????
83754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                }
83854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            };
83954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
84054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            MessageDestroyTexture *msg = new MessageDestroyTexture(
84154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis                    mBufferData[i].texture, dpy);
84254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
84354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Don't allow this texture to be cleaned up by
84454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // BufferManager::destroy.
84554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.name = -1U;
84654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
84754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
84854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            // Post the message to the SurfaceFlinger object.
84954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis            flinger->postMessageAsync(msg);
85054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        }
85154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
85254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
853bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    mNumBuffers = size;
854bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
855d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
856d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
857d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// only for debugging
858d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
859d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mBufferData[index].buffer;
860d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
861d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
862d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
863420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    BufferData const * const buffers = mBufferData;
864420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    Mutex::Autolock _l(mLock);
865420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBuffer = buffers[index].buffer;
866420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    mActiveBufferIndex = index;
867d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
868d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
869d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
870d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansize_t Layer::BufferManager::getActiveBufferIndex() const {
871420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex;
872d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
873d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
874d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias AgopianTexture Layer::BufferManager::getActiveTexture() const {
875bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    Texture res;
876420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    if (mFailover || mActiveBufferIndex<0) {
877bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        res = mFailoverTexture;
878bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } else {
879420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian        static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture;
880bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
881bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
882d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
883d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
884d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
885420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBuffer;
886d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
887d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
888da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopianbool Layer::BufferManager::hasActiveBuffer() const {
889420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    return mActiveBufferIndex >= 0;
890da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian}
891da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
892d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopiansp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
893d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
894bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
895d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    sp<GraphicBuffer> buffer;
896d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
897bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffer = buffers[index].buffer;
898bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = 0;
899d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return buffer;
900d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
901d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
902d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::attachBuffer(size_t index,
903d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
904d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
905bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
906d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    Mutex::Autolock _l(mLock);
907bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].buffer = buffer;
908bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    buffers[index].texture.dirty = true;
909d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
910d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
911d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
912d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::destroy(EGLDisplay dpy)
913d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
914bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    BufferData* const buffers = mBufferData;
915bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    size_t num;
916bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    { // scope for the lock
917bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        Mutex::Autolock _l(mLock);
918bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        num = mNumBuffers;
919bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        for (size_t i=0 ; i<num ; i++) {
920bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            buffers[i].buffer = 0;
921bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
922bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
923bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    for (size_t i=0 ; i<num ; i++) {
924bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        destroyTexture(&buffers[i].texture, dpy);
925d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
926d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    destroyTexture(&mFailoverTexture, dpy);
927d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return NO_ERROR;
928d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
929d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
930d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
931d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const sp<GraphicBuffer>& buffer)
932d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
933b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = NO_INIT;
934420a283c4dc2a669c93bd5c0a2180b14f3625501Mathias Agopian    ssize_t index = mActiveBufferIndex;
935b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (index >= 0) {
9361f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (!mFailover) {
9371f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            Image& texture(mBufferData[index].texture);
9381f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = mTextureManager.initEglImage(&texture, dpy, buffer);
9391f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // if EGLImage fails, we switch to regular texture mode, and we
9401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // free all resources associated with using EGLImages.
9411f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            if (err == NO_ERROR) {
9421f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = false;
9431f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                destroyTexture(&mFailoverTexture, dpy);
9441f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            } else {
9451f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                mFailover = true;
9461f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                const size_t num = mNumBuffers;
9471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                for (size_t i=0 ; i<num ; i++) {
9481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                    destroyTexture(&mBufferData[i].texture, dpy);
9491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                }
950e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber            }
9511f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        } else {
9521f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // we failed once, don't try again
9531f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            err = BAD_VALUE;
954d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        }
955d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    }
956d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return err;
957d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
958d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
959d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianstatus_t Layer::BufferManager::loadTexture(
960d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        const Region& dirty, const GGLSurface& t)
961d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
962d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
963d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
964d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
965bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
966bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
967bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->name != -1U) {
968bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        glDeleteTextures(1, &tex->name);
969bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->name = -1U;
970bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
971bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (tex->image != EGL_NO_IMAGE_KHR) {
972bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        eglDestroyImageKHR(dpy, tex->image);
973bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        tex->image = EGL_NO_IMAGE_KHR;
974bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
975bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return NO_ERROR;
976bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
977bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
978d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// ---------------------------------------------------------------------------
979d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
9809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
98196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Layer>& owner)
98296f0819f81293076e652792794a961543e6750d7Mathias Agopian    : Surface(flinger, owner->getIdentity(), owner)
9839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
9849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
9859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
9869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayer::SurfaceLayer::~SurfaceLayer()
987076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
988076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
989076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
990a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopiansp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
991a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
992076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
9933330b203039dea366d4981db1408a460134b2d2cMathias Agopian    sp<GraphicBuffer> buffer;
994076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> owner(getOwner());
995076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (owner != 0) {
996bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
997bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * requestBuffer() cannot be called from the main thread
998bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
999bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1000bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1001a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        buffer = owner->requestBuffer(index, w, h, format, usage);
1002076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1003076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return buffer;
1004076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1006b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianstatus_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
1007b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
1008b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    status_t err = DEAD_OBJECT;
1009b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<Layer> owner(getOwner());
1010b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (owner != 0) {
1011bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        /*
1012bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * setBufferCount() cannot be called from the main thread
1013bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * as it could cause a dead-lock, since it may have to wait
1014bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         * on conditions updated my the main thread.
1015bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian         */
1016b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian        err = owner->setBufferCount(bufferCount);
1017b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
1018b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
1019b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1020b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1025