blob: e621b22a05a196142d6b868c0bc8069a5b201a07 [file] [log] [blame]
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SurfaceControl"
18
19#include <stdint.h>
20#include <errno.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23
24#include <android/native_window.h>
25
26#include <utils/CallStack.h>
27#include <utils/Errors.h>
28#include <utils/Log.h>
29#include <utils/threads.h>
30
31#include <binder/IPCThreadState.h>
32
33#include <ui/DisplayInfo.h>
34#include <ui/GraphicBuffer.h>
35#include <ui/Rect.h>
36
37#include <gui/ISurface.h>
38#include <gui/ISurfaceComposer.h>
39#include <gui/Surface.h>
40#include <gui/SurfaceComposerClient.h>
41#include <gui/SurfaceControl.h>
42
43namespace android {
44
45// ============================================================================
46// SurfaceControl
47// ============================================================================
48
49SurfaceControl::SurfaceControl(
50 const sp<SurfaceComposerClient>& client,
51 const sp<ISurface>& surface)
52 : mClient(client)
53{
54 if (surface != 0) {
55 mSurface = surface->asBinder();
56 mGraphicBufferProducer = surface->getSurfaceTexture();
57 }
58}
59
60SurfaceControl::~SurfaceControl()
61{
62 destroy();
63}
64
65void SurfaceControl::destroy()
66{
67 if (isValid()) {
68 mClient->destroySurface(mSurface);
69 }
70 // clear all references and trigger an IPC now, to make sure things
71 // happen without delay, since these resources are quite heavy.
72 mClient.clear();
73 mSurface.clear();
74 mGraphicBufferProducer.clear();
75 IPCThreadState::self()->flushCommands();
76}
77
78void SurfaceControl::clear()
79{
80 // here, the window manager tells us explicitly that we should destroy
81 // the surface's resource. Soon after this call, it will also release
82 // its last reference (which will call the dtor); however, it is possible
83 // that a client living in the same process still holds references which
84 // would delay the call to the dtor -- that is why we need this explicit
85 // "clear()" call.
86 destroy();
87}
88
89bool SurfaceControl::isSameSurface(
90 const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
91{
92 if (lhs == 0 || rhs == 0)
93 return false;
94 return lhs->mSurface == rhs->mSurface;
95}
96
97status_t SurfaceControl::setLayerStack(int32_t layerStack) {
98 status_t err = validate();
99 if (err < 0) return err;
100 const sp<SurfaceComposerClient>& client(mClient);
101 return client->setLayerStack(mSurface, layerStack);
102}
103status_t SurfaceControl::setLayer(int32_t layer) {
104 status_t err = validate();
105 if (err < 0) return err;
106 const sp<SurfaceComposerClient>& client(mClient);
107 return client->setLayer(mSurface, layer);
108}
Ramanan Rajeswarand6480c02013-03-21 15:49:59 +0000109status_t SurfaceControl::setPosition(float x, float y) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800110 status_t err = validate();
111 if (err < 0) return err;
112 const sp<SurfaceComposerClient>& client(mClient);
113 return client->setPosition(mSurface, x, y);
114}
115status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
116 status_t err = validate();
117 if (err < 0) return err;
118 const sp<SurfaceComposerClient>& client(mClient);
119 return client->setSize(mSurface, w, h);
120}
121status_t SurfaceControl::hide() {
122 status_t err = validate();
123 if (err < 0) return err;
124 const sp<SurfaceComposerClient>& client(mClient);
125 return client->hide(mSurface);
126}
127status_t SurfaceControl::show() {
128 status_t err = validate();
129 if (err < 0) return err;
130 const sp<SurfaceComposerClient>& client(mClient);
131 return client->show(mSurface);
132}
133status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
134 status_t err = validate();
135 if (err < 0) return err;
136 const sp<SurfaceComposerClient>& client(mClient);
137 return client->setFlags(mSurface, flags, mask);
138}
139status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
140 status_t err = validate();
141 if (err < 0) return err;
142 const sp<SurfaceComposerClient>& client(mClient);
143 return client->setTransparentRegionHint(mSurface, transparent);
144}
145status_t SurfaceControl::setAlpha(float alpha) {
146 status_t err = validate();
147 if (err < 0) return err;
148 const sp<SurfaceComposerClient>& client(mClient);
149 return client->setAlpha(mSurface, alpha);
150}
151status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
152 status_t err = validate();
153 if (err < 0) return err;
154 const sp<SurfaceComposerClient>& client(mClient);
155 return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy);
156}
157status_t SurfaceControl::setCrop(const Rect& crop) {
158 status_t err = validate();
159 if (err < 0) return err;
160 const sp<SurfaceComposerClient>& client(mClient);
161 return client->setCrop(mSurface, crop);
162}
163
164status_t SurfaceControl::validate() const
165{
166 if (mSurface==0 || mClient==0) {
167 ALOGE("invalid ISurface (%p) or client (%p)",
168 mSurface.get(), mClient.get());
169 return NO_INIT;
170 }
171 return NO_ERROR;
172}
173
174status_t SurfaceControl::writeSurfaceToParcel(
175 const sp<SurfaceControl>& control, Parcel* parcel)
176{
177 sp<IGraphicBufferProducer> bp;
178 if (control != NULL) {
179 bp = control->mGraphicBufferProducer;
180 }
181 return parcel->writeStrongBinder(bp->asBinder());
182}
183
184sp<Surface> SurfaceControl::getSurface() const
185{
186 Mutex::Autolock _l(mLock);
187 if (mSurfaceData == 0) {
188 mSurfaceData = new Surface(mGraphicBufferProducer);
189 }
190 return mSurfaceData;
191}
192
193// ----------------------------------------------------------------------------
194}; // namespace android