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(const sp<SurfaceControl>& other) {
     58     mClient = other->mClient;
     59     mHandle = other->mHandle;
     60     mGraphicBufferProducer = other->mGraphicBufferProducer;
     61     mOwned = false;
     62 }
     63 
     64 SurfaceControl::~SurfaceControl()
     65 {
     66     // Avoid reparenting the server-side surface to null if we are not the owner of it,
     67     // meaning that we retrieved it from another process.
     68     if (mClient != nullptr && mHandle != nullptr && mOwned) {
     69         SurfaceComposerClient::doDropReferenceTransaction(mHandle, mClient->getClient());
     70     }
     71     release();
     72 }
     73 
     74 void SurfaceControl::destroy()
     75 {
     76     if (isValid()) {
     77         SurfaceComposerClient::Transaction().reparent(this, nullptr).apply();
     78     }
     79     release();
     80 }
     81 
     82 void SurfaceControl::release()
     83 {
     84     // Trigger an IPC now, to make sure things
     85     // happen without delay, since these resources are quite heavy.
     86     mClient.clear();
     87     mHandle.clear();
     88     mGraphicBufferProducer.clear();
     89     IPCThreadState::self()->flushCommands();
     90 }
     91 
     92 void SurfaceControl::disconnect() {
     93     if (mGraphicBufferProducer != nullptr) {
     94         mGraphicBufferProducer->disconnect(
     95                 BufferQueueCore::CURRENTLY_CONNECTED_API);
     96     }
     97 }
     98 
     99 bool SurfaceControl::isSameSurface(
    100         const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
    101 {
    102     if (lhs == nullptr || rhs == nullptr)
    103         return false;
    104     return lhs->mHandle == rhs->mHandle;
    105 }
    106 
    107 status_t SurfaceControl::clearLayerFrameStats() const {
    108     status_t err = validate();
    109     if (err != NO_ERROR) return err;
    110     const sp<SurfaceComposerClient>& client(mClient);
    111     return client->clearLayerFrameStats(mHandle);
    112 }
    113 
    114 status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const {
    115     status_t err = validate();
    116     if (err != NO_ERROR) return err;
    117     const sp<SurfaceComposerClient>& client(mClient);
    118     return client->getLayerFrameStats(mHandle, outStats);
    119 }
    120 
    121 status_t SurfaceControl::validate() const
    122 {
    123     if (mHandle==nullptr || mClient==nullptr) {
    124         ALOGE("invalid handle (%p) or client (%p)",
    125                 mHandle.get(), mClient.get());
    126         return NO_INIT;
    127     }
    128     return NO_ERROR;
    129 }
    130 
    131 status_t SurfaceControl::writeSurfaceToParcel(
    132         const sp<SurfaceControl>& control, Parcel* parcel)
    133 {
    134     sp<IGraphicBufferProducer> bp;
    135     if (control != nullptr) {
    136         bp = control->mGraphicBufferProducer;
    137     }
    138     return parcel->writeStrongBinder(IInterface::asBinder(bp));
    139 }
    140 
    141 sp<Surface> SurfaceControl::generateSurfaceLocked() const
    142 {
    143     // This surface is always consumed by SurfaceFlinger, so the
    144     // producerControlledByApp value doesn't matter; using false.
    145     mSurfaceData = new Surface(mGraphicBufferProducer, false);
    146 
    147     return mSurfaceData;
    148 }
    149 
    150 sp<Surface> SurfaceControl::getSurface() const
    151 {
    152     Mutex::Autolock _l(mLock);
    153     if (mSurfaceData == nullptr) {
    154         return generateSurfaceLocked();
    155     }
    156     return mSurfaceData;
    157 }
    158 
    159 sp<Surface> SurfaceControl::createSurface() const
    160 {
    161     Mutex::Autolock _l(mLock);
    162     return generateSurfaceLocked();
    163 }
    164 
    165 sp<IBinder> SurfaceControl::getHandle() const
    166 {
    167     Mutex::Autolock lock(mLock);
    168     return mHandle;
    169 }
    170 
    171 sp<IGraphicBufferProducer> SurfaceControl::getIGraphicBufferProducer() const
    172 {
    173     Mutex::Autolock _l(mLock);
    174     return mGraphicBufferProducer;
    175 }
    176 
    177 sp<SurfaceComposerClient> SurfaceControl::getClient() const
    178 {
    179     return mClient;
    180 }
    181 
    182 void SurfaceControl::writeToParcel(Parcel* parcel)
    183 {
    184     parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
    185     parcel->writeStrongBinder(mHandle);
    186     parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
    187 }
    188 
    189 sp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel)
    190 {
    191     sp<IBinder> client = parcel->readStrongBinder();
    192     sp<IBinder> handle = parcel->readStrongBinder();
    193     if (client == nullptr || handle == nullptr)
    194     {
    195         ALOGE("Invalid parcel");
    196         return nullptr;
    197     }
    198     sp<IBinder> gbp;
    199     parcel->readNullableStrongBinder(&gbp);
    200 
    201     // We aren't the original owner of the surface.
    202     return new SurfaceControl(new SurfaceComposerClient(
    203                     interface_cast<ISurfaceComposerClient>(client)),
    204             handle.get(), interface_cast<IGraphicBufferProducer>(gbp), false /* owned */);
    205 }
    206 
    207 // ----------------------------------------------------------------------------
    208 }; // namespace android
    209