LayerBase.cpp revision 78fd5010a87425d2be401d10a306dd68638fc1dd
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 <utils/Errors.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
23310f8da0c3122ed5419db8f12a6e98d3188325b2Mathias Agopian#include <binder/IPCThreadState.h>
24310f8da0c3122ed5419db8f12a6e98d3188325b2Mathias Agopian#include <binder/IServiceManager.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/glext.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <hardware/hardware.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBase.h"
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t LayerBase::typeInfo = 1;
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const LayerBase::typeID = "LayerBase";
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const LayerBaseClient::typeID = "LayerBaseClient";
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : dpy(display), contentDirty(false),
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mFlinger(flinger),
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mTransformed(false),
53a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian      mUseLinearFiltering(false),
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mOrientation(0),
55ca6fab2b534fc7b252d0ee7ec2079afff7e5c308Mathias Agopian      mLeft(0), mTop(0),
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mTransactionFlags(0),
57d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian      mPremultipliedAlpha(true), mDebug(false),
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mInvalidate(0)
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFlags = hw.getFlags();
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBase::~LayerBase()
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopianvoid LayerBase::setName(const String8& name) {
69d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian    mName = name;
70d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian}
71d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian
72d12965934712ed0b9c1a264a6934dc0dad839ffdMathias AgopianString8 LayerBase::getName() const {
73d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian    return mName;
74d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian}
75d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& LayerBase::graphicPlane(int dpy) const
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlinger->graphicPlane(dpy);
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& LayerBase::graphicPlane(int dpy)
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlinger->graphicPlane(dpy);
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t layerFlags = 0;
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags & ISurfaceComposer::eHidden)
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layerFlags = ISurfaceComposer::eLayerHidden;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags & ISurfaceComposer::eNonPremultiplied)
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPremultipliedAlpha = false;
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
957e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.z             = 0;
967e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.w             = w;
977e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.h             = h;
987e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.requested_w   = w;
997e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.requested_h   = h;
1007e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.alpha         = 0xFF;
1017e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.flags         = layerFlags;
1027e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.sequence      = 0;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.transform.set(0, 0);
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // drawing state & current state are identical
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
109ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopianvoid LayerBase::commitTransaction() {
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::forceVisibilityTransaction() {
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this can be called without SurfaceFlinger.mStateLock, but if we
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // can atomically increment the sequence number, it doesn't matter.
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mCurrentState.sequence);
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::requestTransaction() {
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t old = setTransactionFlags(eTransactionNeeded);
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ((old & eTransactionNeeded) == 0);
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::getTransactionFlags(uint32_t flags) {
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::setTransactionFlags(uint32_t flags) {
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_or(flags, &mTransactionFlags);
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setPosition(int32_t x, int32_t y) {
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.transform.set(x, y);
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setLayer(uint32_t z) {
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.z == z)
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.z = z;
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setSize(uint32_t w, uint32_t h) {
1467e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
1487e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.requested_w = w;
1497e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    mCurrentState.requested_h = h;
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setAlpha(uint8_t alpha) {
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.alpha == alpha)
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.alpha = alpha;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: check the matrix has changed
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.transform.set(
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setTransparentRegionHint(const Region& transparent) {
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: check the region has changed
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.transparentRegion = transparent;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.flags == newFlags)
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.sequence++;
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.flags = newFlags;
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    requestTransaction();
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect LayerBase::visibleBounds() const
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mTransformedBounds;
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setVisibleRegion(const Region& visibleRegion) {
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // always called from main thread
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegionScreen = visibleRegion;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setCoveredRegion(const Region& coveredRegion) {
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // always called from main thread
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    coveredRegionScreen = coveredRegion;
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::doTransaction(uint32_t flags)
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2067e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    if ((front.requested_w != temp.requested_w) ||
2077e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        (front.requested_h != temp.requested_h))  {
2087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        // resize the layer, set the physical size to the requested size
2097e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        Layer::State& editTemp(currentState());
2107e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        editTemp.w = temp.requested_w;
2117e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian        editTemp.h = temp.requested_h;
2127e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian    }
2136656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian
2146656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian    if ((front.w != temp.w) || (front.h != temp.h)) {
2156656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        // invalidate and recompute the visible regions if needed
2166656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian        flags |= Layer::eVisibleRegion;
2176656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian    }
2187e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (temp.sequence != front.sequence) {
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // invalidate and recompute the visible regions if needed
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        flags |= eVisibleRegion;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        this->contentDirty = true;
223a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian
224a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        const bool linearFiltering = mUseLinearFiltering;
225a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        mUseLinearFiltering = false;
226a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
227a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian            // we may use linear filtering, if the matrix scales us
228a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian            const uint8_t type = temp.transform.getType();
229a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian            if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) {
230a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian                mUseLinearFiltering = true;
231a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian            }
232a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        }
233a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    }
234a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Commit the transaction
236ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopian    commitTransaction();
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return flags;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateVisibility(const Transform& planeTransform)
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& s(drawingState());
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform tr(planeTransform * s.transform);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool transformed = tr.transformed();
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
246cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    uint32_t w = s.w;
247cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    uint32_t h = s.h;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr.transform(mVertices[0], 0, 0);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr.transform(mVertices[1], 0, h);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr.transform(mVertices[2], w, h);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr.transform(mVertices[3], w, 0);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(transformed)) {
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // NOTE: here we could also punt if we have too many rectangles
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // in the transparent region
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (tr.preserveRects()) {
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // transform the transparent region
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            transparentRegionScreen = tr.transform(s.transparentRegion);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // transformation too complex, can't do the transparent region
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // optimization.
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            transparentRegionScreen.clear();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        transparentRegionScreen = s.transparentRegion;
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // cache a few things...
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mOrientation = tr.getOrientation();
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransformedBounds = tr.makeBounds(w, h);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransformed = transformed;
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLeft = tr.tx();
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTop  = tr.ty();
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::unlockPageFlip(
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outDirtyRegion.orSelf(visibleRegionScreen);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::finishPageFlip()
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::invalidate()
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFlinger->signalEvent();
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::drawRegion(const Region& reg) const
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = reg.begin();
30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = reg.end();
30220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    if (it != end) {
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Rect r;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t fbWidth  = hw.getWidth();
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t fbHeight = hw.getHeight();
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { fbWidth, fbHeight }, { 0, fbHeight }  };
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
31020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
31120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = fbHeight - (r.top + r.height());
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::draw(const Region& inClip) const
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // invalidate the region we'll update
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region clip(inClip);  // copy-on-write, so no-op most of the time
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Remove the transparent area from the clipping region
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const State& s = drawingState();
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!s.transparentRegion.isEmpty())) {
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        clip.subtract(transparentRegionScreen);
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (clip.isEmpty()) {
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // usually this won't happen because this should be taken care of
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // by SurfaceFlinger::computeVisibleRegions()
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // reset GL state
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    onDraw(clip);
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_TEXTURE_2D);
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_BLEND);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glColor4x(0, 0x8000, 0, 0x10000);
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawRegion(transparentRegionScreen);
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    */
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGLuint LayerBase::createTexture() const
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLuint textureName = -1;
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &textureName);
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, textureName);
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
358a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
359a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return textureName;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36329aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
36429aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin                                GLclampx green, GLclampx blue,
36529aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin                                GLclampx alpha) const
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t fbHeight = hw.getHeight();
36929aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin    glColor4x(red,green,blue,alpha);
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_TEXTURE_2D);
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
37320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
37420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = clip.begin();
37520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = clip.end();
37695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    glEnable(GL_SCISSOR_TEST);
37778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, mVertices);
37895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    while (it != end) {
37995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        const Rect& r = *it++;
38095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        const GLint sy = fbHeight - (r.top + r.height());
38195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        glScissor(r.left, sy, r.width(), r.height());
38295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38629aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip) const
38729aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin{
38829aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin    clearWithOpenGL(clip,0,0,0,0);
38929aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin}
39029aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin
3911fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopianvoid LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t fbHeight = hw.getHeight();
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const State& s(drawingState());
3960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind our texture
3981fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian    validateTexture(texture.name);
3991fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian    uint32_t width  = texture.width;
4001fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian    uint32_t height = texture.height;
4011fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_TEXTURE_2D);
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(s.alpha < 0xFF)) {
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // We have an alpha-modulation. We need to modulate all
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // texture components by alpha because we're always using
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // premultiplied alpha.
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // If the texture doesn't have an alpha channel we can
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // use REPLACE and switch to non premultiplied alpha
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // blending (SRCA/ONE_MINUS_SRCA).
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum env, src;
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (needsBlending()) {
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            env = GL_MODULATE;
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            env = GL_REPLACE;
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            src = GL_SRC_ALPHA;
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
42178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        const GLfloat alpha = s.alpha * (1.0f/255.0f);
42278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        glColor4f(alpha, alpha, alpha, alpha);
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_BLEND);
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
42878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        glColor4f(1, 1, 1, 1);
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (needsBlending()) {
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glEnable(GL_BLEND);
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDisable(GL_BLEND);
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    Region::const_iterator it = clip.begin();
43995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    Region::const_iterator const end = clip.end();
44078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    const GLfloat texCoords[4][2] = {
44178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            { 0,  0 },
44278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            { 0,  1 },
44378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            { 1,  1 },
44478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            { 1,  0 }
44578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    };
44678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian
44778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glMatrixMode(GL_TEXTURE);
44878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glLoadIdentity();
44978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian
45078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    // the texture's source is rotated
45178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    switch (texture.transform) {
45278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        case HAL_TRANSFORM_ROT_90:
45378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glTranslatef(0, 1, 0);
45478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glRotatef(-90, 0, 0, 1);
45578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            break;
45678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        case HAL_TRANSFORM_ROT_180:
45778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glTranslatef(1, 1, 0);
45878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glRotatef(-180, 0, 0, 1);
45978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            break;
46078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        case HAL_TRANSFORM_ROT_270:
46178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glTranslatef(1, 0, 0);
46278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            glRotatef(-270, 0, 0, 1);
46378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian            break;
46478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    }
4655994a330ac949e7706540f22cd73d76d9f2a96cbChih-Chung Chang
46678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    if (texture.NPOTAdjust) {
46778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        glScalef(texture.wScale, texture.hScale, 1.0f);
46878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    }
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
47178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, mVertices);
47278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    while (it != end) {
47578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        const Rect& r = *it++;
47678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        const GLint sy = fbHeight - (r.top + r.height());
47778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        glScissor(r.left, sy, r.width(), r.height());
47878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
48078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateTexture(GLint textureName) const
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, textureName);
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: reload the texture if needed
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this is currently done in loadTexture() below
488a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    if (mUseLinearFiltering) {
489a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
490a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
491a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    } else {
492a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
493a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
494a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian    }
495401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
496401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    if (needsDithering()) {
497401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        glEnable(GL_DITHER);
498401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    } else {
499401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian        glDisable(GL_DITHER);
500401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    }
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50354ed4f6282bdea251455f39b978626026affdbefMathias Agopianbool LayerBase::isSupportedYuvFormat(int format) const
50454ed4f6282bdea251455f39b978626026affdbefMathias Agopian{
50554ed4f6282bdea251455f39b978626026affdbefMathias Agopian    switch (format) {
50654ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
50754ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
50854ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_422_P:
50954ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_420_P:
51054ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_422_I:
51154ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCbCr_420_I:
51254ed4f6282bdea251455f39b978626026affdbefMathias Agopian        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
51354ed4f6282bdea251455f39b978626026affdbefMathias Agopian            return true;
51454ed4f6282bdea251455f39b978626026affdbefMathias Agopian    }
51554ed4f6282bdea251455f39b978626026affdbefMathias Agopian    return false;
51654ed4f6282bdea251455f39b978626026affdbefMathias Agopian}
51754ed4f6282bdea251455f39b978626026affdbefMathias Agopian
5183330b203039dea366d4981db1408a460134b2d2cMathias Agopianvoid LayerBase::loadTexture(Texture* texture,
5191fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian        const Region& dirty, const GGLSurface& t) const
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5213330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (texture->name == -1U) {
5223330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // uh?
5233330b203039dea366d4981db1408a460134b2d2cMathias Agopian        return;
5243330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
52557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian
5263330b203039dea366d4981db1408a460134b2d2cMathias Agopian    glBindTexture(GL_TEXTURE_2D, texture->name);
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
530076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian     * GL_UNPACK_ALIGNMENT is a limited form of stride).
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * need to do something reasonable (here creating a bigger texture).
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * This situation doesn't happen often, but some h/w have a limitation
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * for their framebuffer (eg: must be multiple of 8 pixels), and
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * we need to take that into account when using these buffers as
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * textures.
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * This should never be a problem with POT textures
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    unpack = 1 << ((unpack > 3) ? 3 : unpack);
546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * round to POT if needed
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
5513330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
5523330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->NPOTAdjust = true;
5533330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5553330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (texture->NPOTAdjust) {
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // find the smallest power-of-two that will accommodate our surface
5573330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->potWidth  = 1 << (31 - clz(t.width));
5583330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->potHeight = 1 << (31 - clz(t.height));
5593330b203039dea366d4981db1408a460134b2d2cMathias Agopian        if (texture->potWidth  < t.width)  texture->potWidth  <<= 1;
5603330b203039dea366d4981db1408a460134b2d2cMathias Agopian        if (texture->potHeight < t.height) texture->potHeight <<= 1;
5613330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->wScale = float(t.width)  / texture->potWidth;
5623330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->hScale = float(t.height) / texture->potHeight;
5633330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
5643330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->potWidth  = t.width;
5653330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->potHeight = t.height;
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
5673330b203039dea366d4981db1408a460134b2d2cMathias Agopian
568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Rect bounds(dirty.bounds());
569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    GLvoid* data = 0;
5703330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (texture->width != t.width || texture->height != t.height) {
5713330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->width  = t.width;
5723330b203039dea366d4981db1408a460134b2d2cMathias Agopian        texture->height = t.height;
573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5743330b203039dea366d4981db1408a460134b2d2cMathias Agopian        // texture size changed, we need to create a new one
5753330b203039dea366d4981db1408a460134b2d2cMathias Agopian        bounds.set(Rect(t.width, t.height));
5763330b203039dea366d4981db1408a460134b2d2cMathias Agopian        if (t.width  == texture->potWidth &&
5773330b203039dea366d4981db1408a460134b2d2cMathias Agopian            t.height == texture->potHeight) {
5783330b203039dea366d4981db1408a460134b2d2cMathias Agopian            // we can do it one pass
5793330b203039dea366d4981db1408a460134b2d2cMathias Agopian            data = t.data;
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
5813330b203039dea366d4981db1408a460134b2d2cMathias Agopian
58254ed4f6282bdea251455f39b978626026affdbefMathias Agopian        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexImage2D(GL_TEXTURE_2D, 0,
5843330b203039dea366d4981db1408a460134b2d2cMathias Agopian                    GL_RGB, texture->potWidth, texture->potHeight, 0,
585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
58654ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexImage2D(GL_TEXTURE_2D, 0,
5883330b203039dea366d4981db1408a460134b2d2cMathias Agopian                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
59054ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
59154ed4f6282bdea251455f39b978626026affdbefMathias Agopian                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexImage2D(GL_TEXTURE_2D, 0,
5933330b203039dea366d4981db1408a460134b2d2cMathias Agopian                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGBA, GL_UNSIGNED_BYTE, data);
59554ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (isSupportedYuvFormat(t.format)) {
596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // just show the Y plane of YUV buffers
597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexImage2D(GL_TEXTURE_2D, 0,
5983330b203039dea366d4981db1408a460134b2d2cMathias Agopian                    GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        } else {
601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // oops, we don't handle this format!
602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            LOGE("layer %p, texture=%d, using format %d, which is not "
6033330b203039dea366d4981db1408a460134b2d2cMathias Agopian                 "supported by the GL", this, texture->name, t.format);
604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
6063330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (!data) {
60754ed4f6282bdea251455f39b978626026affdbefMathias Agopian        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexSubImage2D(GL_TEXTURE_2D, 0,
609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    0, bounds.top, t.width, bounds.height(),
610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    t.data + bounds.top*t.stride*2);
61254ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexSubImage2D(GL_TEXTURE_2D, 0,
614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    0, bounds.top, t.width, bounds.height(),
615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    t.data + bounds.top*t.stride*2);
61754ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
61854ed4f6282bdea251455f39b978626026affdbefMathias Agopian                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexSubImage2D(GL_TEXTURE_2D, 0,
620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    0, bounds.top, t.width, bounds.height(),
621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_RGBA, GL_UNSIGNED_BYTE,
622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    t.data + bounds.top*t.stride*4);
62354ed4f6282bdea251455f39b978626026affdbefMathias Agopian        } else if (isSupportedYuvFormat(t.format)) {
624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // just show the Y plane of YUV buffers
625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            glTexSubImage2D(GL_TEXTURE_2D, 0,
626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    0, bounds.top, t.width, bounds.height(),
627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    t.data + bounds.top*t.stride);
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopianstatus_t LayerBase::initializeEglImage(
63454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        const sp<GraphicBuffer>& buffer, Texture* texture)
63554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian{
63654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    status_t err = NO_ERROR;
63754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
63854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    // we need to recreate the texture
63954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
64054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
64154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    // free the previous image
64254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    if (texture->image != EGL_NO_IMAGE_KHR) {
64354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        eglDestroyImageKHR(dpy, texture->image);
64454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        texture->image = EGL_NO_IMAGE_KHR;
64554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    }
64654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
64754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    // construct an EGL_NATIVE_BUFFER_ANDROID
64854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
64954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
65054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    // create the new EGLImageKHR
65154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    const EGLint attrs[] = {
65254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
65354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            EGL_NONE,                   EGL_NONE
65454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    };
65554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    texture->image = eglCreateImageKHR(
65654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
65754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            (EGLClientBuffer)clientBuf, attrs);
65854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
65954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    if (texture->image != EGL_NO_IMAGE_KHR) {
66054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        glBindTexture(GL_TEXTURE_2D, texture->name);
66154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
66254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian                (GLeglImageOES)texture->image);
66354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        GLint error = glGetError();
66454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        if (UNLIKELY(error != GL_NO_ERROR)) {
66554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
66654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian                 "failed err=0x%04x",
66754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian                 this, texture->image, error);
66854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            err = INVALID_OPERATION;
66954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        } else {
67054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            // Everything went okay!
67154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            texture->NPOTAdjust = false;
67254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            texture->dirty  = false;
67354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            texture->width  = clientBuf->width;
67454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian            texture->height = clientBuf->height;
67554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        }
67654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    } else {
677fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian        LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x",
678fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian                this, eglGetError());
67954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        err = INVALID_OPERATION;
68054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    }
68154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    return err;
68254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian}
68354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
68454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6872e123245811a1f31c080a29728fcc1655045f011Mathias Agopianint32_t LayerBaseClient::sIdentity = 0;
6882e123245811a1f31c080a29728fcc1655045f011Mathias Agopian
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
690f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, int32_t i)
691d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian    : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
692948d69fca450a5a85e3e3e17d5776bfb26e48b85Mathias Agopian      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
69448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    lcblk = new SharedBufferServer(
69548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            client->ctrlblk, i, NUM_BUFFERS,
69648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mIdentity);
697076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
699076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::onFirstRef()
700076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
701f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client(this->client.promote());
702f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (client != 0) {
703076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        client->bindLayer(this, mIndex);
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::~LayerBaseClient()
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
709f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client(this->client.promote());
710f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (client != 0) {
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        client->free(mIndex);
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
71348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    delete lcblk;
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
716f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianint32_t LayerBaseClient::serverIndex() const
717f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian{
718f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client(this->client.promote());
719f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (client != 0) {
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return (client->cid<<16)|mIndex;
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0xFFFF0000 | mIndex;
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
725076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
726076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
727076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Surface> s;
728076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
729076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    s = mClientSurface.promote();
730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (s == 0) {
731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        s = createSurface();
732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mClientSurface = s;
733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
734076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return s;
735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
7399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return new Surface(mFlinger, clientIndex(), mIdentity,
740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const_cast<LayerBaseClient *>(this));
741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
7430b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
7440b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian// in the purgatory list
7450b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopianvoid LayerBaseClient::onRemoved()
7460b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian{
7470b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    // wake up the condition
7480b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    lcblk->setStatus(NO_INIT);
7490b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian}
7500b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
751076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
752076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
7539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::Surface(
7549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        const sp<SurfaceFlinger>& flinger,
7559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        SurfaceID id, int identity,
756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBaseClient>& owner)
7579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
7589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
7619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::~Surface()
7629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
7639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
7649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * This is a good place to clean-up all client resources
7659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
7669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
7679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    // destroy client resources
7689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    sp<LayerBaseClient> layer = getOwner();
7699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    if (layer != 0) {
7709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        mFlinger->destroySurface(layer);
7719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
773076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
774076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
775076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> owner(mOwner.promote());
776076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return owner;
777076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
779076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::onTransact(
780375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
781076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
782076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    switch (code) {
783076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        case REGISTER_BUFFERS:
784076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        case UNREGISTER_BUFFERS:
785076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        case CREATE_OVERLAY:
786076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        {
787375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
788375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                IPCThreadState* ipc = IPCThreadState::self();
789375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                const int pid = ipc->getCallingPid();
790375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                const int uid = ipc->getCallingUid();
791375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
792375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
793375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
794076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
795076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
796076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
797076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return BnSurface::onTransact(code, data, reply, flags);
798076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
799076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
8003330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage)
801076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
802076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NULL;
803076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
804076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
805076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::registerBuffers(
806076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const ISurface::BufferHeap& buffers)
807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return INVALID_OPERATION;
809076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
810076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
811076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::postBuffer(ssize_t offset)
812076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
813076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
814076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
815076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::unregisterBuffers()
816076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
817076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
818076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
819076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<OverlayRef> LayerBaseClient::Surface::createOverlay(
82052e7200b6e020bba978c36e3a928493a3f2c8a92Chih-Chung Chang        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
821076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
822076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NULL;
823076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian};
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
828