Home | History | Annotate | Download | only in gui
      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/ISurfaceComposer.h>
     38 #include <gui/Surface.h>
     39 #include <gui/SurfaceComposerClient.h>
     40 #include <gui/SurfaceControl.h>
     41 
     42 namespace android {
     43 
     44 // ============================================================================
     45 //  SurfaceControl
     46 // ============================================================================
     47 
     48 SurfaceControl::SurfaceControl(
     49         const sp<SurfaceComposerClient>& client,
     50         const sp<IBinder>& handle,
     51         const sp<IGraphicBufferProducer>& gbp)
     52     : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
     53 {
     54 }
     55 
     56 SurfaceControl::~SurfaceControl()
     57 {
     58     destroy();
     59 }
     60 
     61 void SurfaceControl::destroy()
     62 {
     63     if (isValid()) {
     64         mClient->destroySurface(mHandle);
     65     }
     66     // clear all references and trigger an IPC now, to make sure things
     67     // happen without delay, since these resources are quite heavy.
     68     mClient.clear();
     69     mHandle.clear();
     70     mGraphicBufferProducer.clear();
     71     IPCThreadState::self()->flushCommands();
     72 }
     73 
     74 void SurfaceControl::clear()
     75 {
     76     // here, the window manager tells us explicitly that we should destroy
     77     // the surface's resource. Soon after this call, it will also release
     78     // its last reference (which will call the dtor); however, it is possible
     79     // that a client living in the same process still holds references which
     80     // would delay the call to the dtor -- that is why we need this explicit
     81     // "clear()" call.
     82     destroy();
     83 }
     84 
     85 bool SurfaceControl::isSameSurface(
     86         const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
     87 {
     88     if (lhs == 0 || rhs == 0)
     89         return false;
     90     return lhs->mHandle == rhs->mHandle;
     91 }
     92 
     93 status_t SurfaceControl::setLayerStack(int32_t layerStack) {
     94     status_t err = validate();
     95     if (err < 0) return err;
     96     const sp<SurfaceComposerClient>& client(mClient);
     97     return client->setLayerStack(mHandle, layerStack);
     98 }
     99 status_t SurfaceControl::setLayer(int32_t layer) {
    100     status_t err = validate();
    101     if (err < 0) return err;
    102     const sp<SurfaceComposerClient>& client(mClient);
    103     return client->setLayer(mHandle, layer);
    104 }
    105 status_t SurfaceControl::setPosition(float x, float y) {
    106     status_t err = validate();
    107     if (err < 0) return err;
    108     const sp<SurfaceComposerClient>& client(mClient);
    109     return client->setPosition(mHandle, x, y);
    110 }
    111 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
    112     status_t err = validate();
    113     if (err < 0) return err;
    114     const sp<SurfaceComposerClient>& client(mClient);
    115     return client->setSize(mHandle, w, h);
    116 }
    117 status_t SurfaceControl::hide() {
    118     status_t err = validate();
    119     if (err < 0) return err;
    120     const sp<SurfaceComposerClient>& client(mClient);
    121     return client->hide(mHandle);
    122 }
    123 status_t SurfaceControl::show() {
    124     status_t err = validate();
    125     if (err < 0) return err;
    126     const sp<SurfaceComposerClient>& client(mClient);
    127     return client->show(mHandle);
    128 }
    129 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
    130     status_t err = validate();
    131     if (err < 0) return err;
    132     const sp<SurfaceComposerClient>& client(mClient);
    133     return client->setFlags(mHandle, flags, mask);
    134 }
    135 status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
    136     status_t err = validate();
    137     if (err < 0) return err;
    138     const sp<SurfaceComposerClient>& client(mClient);
    139     return client->setTransparentRegionHint(mHandle, transparent);
    140 }
    141 status_t SurfaceControl::setAlpha(float alpha) {
    142     status_t err = validate();
    143     if (err < 0) return err;
    144     const sp<SurfaceComposerClient>& client(mClient);
    145     return client->setAlpha(mHandle, alpha);
    146 }
    147 status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    148     status_t err = validate();
    149     if (err < 0) return err;
    150     const sp<SurfaceComposerClient>& client(mClient);
    151     return client->setMatrix(mHandle, dsdx, dtdx, dsdy, dtdy);
    152 }
    153 status_t SurfaceControl::setCrop(const Rect& crop) {
    154     status_t err = validate();
    155     if (err < 0) return err;
    156     const sp<SurfaceComposerClient>& client(mClient);
    157     return client->setCrop(mHandle, crop);
    158 }
    159 
    160 status_t SurfaceControl::validate() const
    161 {
    162     if (mHandle==0 || mClient==0) {
    163         ALOGE("invalid handle (%p) or client (%p)",
    164                 mHandle.get(), mClient.get());
    165         return NO_INIT;
    166     }
    167     return NO_ERROR;
    168 }
    169 
    170 status_t SurfaceControl::writeSurfaceToParcel(
    171         const sp<SurfaceControl>& control, Parcel* parcel)
    172 {
    173     sp<IGraphicBufferProducer> bp;
    174     if (control != NULL) {
    175         bp = control->mGraphicBufferProducer;
    176     }
    177     return parcel->writeStrongBinder(bp->asBinder());
    178 }
    179 
    180 sp<Surface> SurfaceControl::getSurface() const
    181 {
    182     Mutex::Autolock _l(mLock);
    183     if (mSurfaceData == 0) {
    184         // This surface is always consumed by SurfaceFlinger, so the
    185         // producerControlledByApp value doesn't matter; using false.
    186         mSurfaceData = new Surface(mGraphicBufferProducer, false);
    187     }
    188     return mSurfaceData;
    189 }
    190 
    191 // ----------------------------------------------------------------------------
    192 }; // namespace android
    193