SurfaceControl.cpp revision 9a867a8798fa6ea21f6341db31e38ea64fde6c83
1/*
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}
109status_t SurfaceControl::setPosition(float x, float y) {
110    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
195