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/Errors.h>
     27 #include <utils/Log.h>
     28 #include <utils/threads.h>
     29 
     30 #include <binder/IPCThreadState.h>
     31 
     32 #include <ui/DisplayInfo.h>
     33 #include <ui/GraphicBuffer.h>
     34 #include <ui/Rect.h>
     35 
     36 #include <gui/BufferQueueCore.h>
     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         bool owned)
     53     : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
     54 {
     55 }
     56 
     57 SurfaceControl::~SurfaceControl()
     58 {
     59     destroy();
     60 }
     61 
     62 void SurfaceControl::destroy()
     63 {
     64     // Avoid destroying the server-side surface if we are not the owner of it, meaning that we
     65     // retrieved it from another process.
     66     if (isValid() && mOwned) {
     67         mClient->destroySurface(mHandle);
     68     }
     69     // clear all references and trigger an IPC now, to make sure things
     70     // happen without delay, since these resources are quite heavy.
     71     mClient.clear();
     72     mHandle.clear();
     73     mGraphicBufferProducer.clear();
     74     IPCThreadState::self()->flushCommands();
     75 }
     76 
     77 void SurfaceControl::clear()
     78 {
     79     // here, the window manager tells us explicitly that we should destroy
     80     // the surface's resource. Soon after this call, it will also release
     81     // its last reference (which will call the dtor); however, it is possible
     82     // that a client living in the same process still holds references which
     83     // would delay the call to the dtor -- that is why we need this explicit
     84     // "clear()" call.
     85     destroy();
     86 }
     87 
     88 void SurfaceControl::disconnect() {
     89     if (mGraphicBufferProducer != NULL) {
     90         mGraphicBufferProducer->disconnect(
     91                 BufferQueueCore::CURRENTLY_CONNECTED_API);
     92     }
     93 }
     94 
     95 bool SurfaceControl::isSameSurface(
     96         const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
     97 {
     98     if (lhs == 0 || rhs == 0)
     99         return false;
    100     return lhs->mHandle == rhs->mHandle;
    101 }
    102 
    103 status_t SurfaceControl::clearLayerFrameStats() const {
    104     status_t err = validate();
    105     if (err < 0) return err;
    106     const sp<SurfaceComposerClient>& client(mClient);
    107     return client->clearLayerFrameStats(mHandle);
    108 }
    109 
    110 status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const {
    111     status_t err = validate();
    112     if (err < 0) return err;
    113     const sp<SurfaceComposerClient>& client(mClient);
    114     return client->getLayerFrameStats(mHandle, outStats);
    115 }
    116 
    117 status_t SurfaceControl::validate() const
    118 {
    119     if (mHandle==0 || mClient==0) {
    120         ALOGE("invalid handle (%p) or client (%p)",
    121                 mHandle.get(), mClient.get());
    122         return NO_INIT;
    123     }
    124     return NO_ERROR;
    125 }
    126 
    127 status_t SurfaceControl::writeSurfaceToParcel(
    128         const sp<SurfaceControl>& control, Parcel* parcel)
    129 {
    130     sp<IGraphicBufferProducer> bp;
    131     if (control != NULL) {
    132         bp = control->mGraphicBufferProducer;
    133     }
    134     return parcel->writeStrongBinder(IInterface::asBinder(bp));
    135 }
    136 
    137 sp<Surface> SurfaceControl::generateSurfaceLocked() const
    138 {
    139     // This surface is always consumed by SurfaceFlinger, so the
    140     // producerControlledByApp value doesn't matter; using false.
    141     mSurfaceData = new Surface(mGraphicBufferProducer, false);
    142 
    143     return mSurfaceData;
    144 }
    145 
    146 sp<Surface> SurfaceControl::getSurface() const
    147 {
    148     Mutex::Autolock _l(mLock);
    149     if (mSurfaceData == 0) {
    150         return generateSurfaceLocked();
    151     }
    152     return mSurfaceData;
    153 }
    154 
    155 sp<Surface> SurfaceControl::createSurface() const
    156 {
    157     Mutex::Autolock _l(mLock);
    158     return generateSurfaceLocked();
    159 }
    160 
    161 sp<IBinder> SurfaceControl::getHandle() const
    162 {
    163     Mutex::Autolock lock(mLock);
    164     return mHandle;
    165 }
    166 
    167 sp<SurfaceComposerClient> SurfaceControl::getClient() const
    168 {
    169     return mClient;
    170 }
    171 
    172 void SurfaceControl::writeToParcel(Parcel* parcel)
    173 {
    174     parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
    175     parcel->writeStrongBinder(mHandle);
    176     parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
    177 }
    178 
    179 sp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel)
    180 {
    181     sp<IBinder> client = parcel->readStrongBinder();
    182     sp<IBinder> handle = parcel->readStrongBinder();
    183     if (client == nullptr || handle == nullptr)
    184     {
    185         ALOGE("Invalid parcel");
    186         return nullptr;
    187     }
    188     sp<IBinder> gbp;
    189     parcel->readNullableStrongBinder(&gbp);
    190 
    191     // We aren't the original owner of the surface.
    192     return new SurfaceControl(new SurfaceComposerClient(
    193                     interface_cast<ISurfaceComposerClient>(client)),
    194             handle.get(), interface_cast<IGraphicBufferProducer>(gbp), false /* owned */);
    195 }
    196 
    197 // ----------------------------------------------------------------------------
    198 }; // namespace android
    199