1e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian/* 2e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * Copyright (C) 2007 The Android Open Source Project 3e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * 4e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * you may not use this file except in compliance with the License. 6e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * You may obtain a copy of the License at 7e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * 8e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * 10e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * Unless required by applicable law or agreed to in writing, software 11e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * See the License for the specific language governing permissions and 14e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian * limitations under the License. 15e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian */ 16e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 17e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#define LOG_TAG "SurfaceControl" 18e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 19e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <stdint.h> 20e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <errno.h> 21e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <sys/types.h> 22e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <sys/stat.h> 23e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 24e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <android/native_window.h> 25e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 26e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <utils/Errors.h> 27e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <utils/Log.h> 28e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <utils/threads.h> 29e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 30e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <binder/IPCThreadState.h> 31e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 32e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <ui/DisplayInfo.h> 33e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <ui/GraphicBuffer.h> 34e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <ui/Rect.h> 35e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 361b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang#include <gui/BufferQueueCore.h> 37e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/ISurfaceComposer.h> 38e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 39e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/SurfaceComposerClient.h> 40e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/SurfaceControl.h> 41e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 42e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopiannamespace android { 43e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian// ============================================================================ 45e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian// SurfaceControl 46e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian// ============================================================================ 47e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 48e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias AgopianSurfaceControl::SurfaceControl( 4983cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall const sp<SurfaceComposerClient>& client, 504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const sp<IBinder>& handle, 510b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi const sp<IGraphicBufferProducer>& gbp, 520b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi bool owned) 530b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned) 54e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 55e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 5683cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall 57e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias AgopianSurfaceControl::~SurfaceControl() 58e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 59e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian destroy(); 60e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 61e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 62e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopianvoid SurfaceControl::destroy() 63e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 640b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi // Avoid destroying the server-side surface if we are not the owner of it, meaning that we 650b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi // retrieved it from another process. 660b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi if (isValid() && mOwned) { 674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mClient->destroySurface(mHandle); 68e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian } 69e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // clear all references and trigger an IPC now, to make sure things 70e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // happen without delay, since these resources are quite heavy. 71e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian mClient.clear(); 724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mHandle.clear(); 73e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian mGraphicBufferProducer.clear(); 74e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian IPCThreadState::self()->flushCommands(); 75e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 76e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 7783cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hallvoid SurfaceControl::clear() 78e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 79e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // here, the window manager tells us explicitly that we should destroy 80e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // the surface's resource. Soon after this call, it will also release 81e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // its last reference (which will call the dtor); however, it is possible 82e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // that a client living in the same process still holds references which 83e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // would delay the call to the dtor -- that is why we need this explicit 84e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian // "clear()" call. 85e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian destroy(); 86e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 87e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 881b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhangvoid SurfaceControl::disconnect() { 891b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang if (mGraphicBufferProducer != NULL) { 901b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang mGraphicBufferProducer->disconnect( 911b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang BufferQueueCore::CURRENTLY_CONNECTED_API); 921b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang } 931b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang} 941b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang 95e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopianbool SurfaceControl::isSameSurface( 9683cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 97e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 98e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian if (lhs == 0 || rhs == 0) 99e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian return false; 1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return lhs->mHandle == rhs->mHandle; 101e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 102e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 103d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceControl::clearLayerFrameStats() const { 104d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav status_t err = validate(); 105d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (err < 0) return err; 106d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav const sp<SurfaceComposerClient>& client(mClient); 107d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return client->clearLayerFrameStats(mHandle); 108d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 109d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 110d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const { 111d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav status_t err = validate(); 112d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (err < 0) return err; 113d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav const sp<SurfaceComposerClient>& client(mClient); 114d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return client->getLayerFrameStats(mHandle, outStats); 115d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 116d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 117e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopianstatus_t SurfaceControl::validate() const 118e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (mHandle==0 || mClient==0) { 1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE("invalid handle (%p) or client (%p)", 1214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mHandle.get(), mClient.get()); 122e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian return NO_INIT; 123e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian } 124e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian return NO_ERROR; 125e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 126e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 127e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel( 128e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian const sp<SurfaceControl>& control, Parcel* parcel) 129e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 130e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian sp<IGraphicBufferProducer> bp; 131e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian if (control != NULL) { 132e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian bp = control->mGraphicBufferProducer; 133e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian } 1342ea926bda2fa30f3ba8d0ed2d2395a8ada952e6eMarco Nelissen return parcel->writeStrongBinder(IInterface::asBinder(bp)); 135e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 136e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 1374e623e259c3e8677d57f761a3708423fb2e77e2aBryce Leesp<Surface> SurfaceControl::generateSurfaceLocked() const 1384e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee{ 1394e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee // This surface is always consumed by SurfaceFlinger, so the 1404e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee // producerControlledByApp value doesn't matter; using false. 1414e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee mSurfaceData = new Surface(mGraphicBufferProducer, false); 1424e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee 1434e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee return mSurfaceData; 1444e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee} 1454e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee 146e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopiansp<Surface> SurfaceControl::getSurface() const 147e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian{ 148e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian Mutex::Autolock _l(mLock); 149e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian if (mSurfaceData == 0) { 1504e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee return generateSurfaceLocked(); 151e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian } 152e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian return mSurfaceData; 153e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian} 154e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian 1554e623e259c3e8677d57f761a3708423fb2e77e2aBryce Leesp<Surface> SurfaceControl::createSurface() const 1564e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee{ 1574e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee Mutex::Autolock _l(mLock); 1584e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee return generateSurfaceLocked(); 1594e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee} 1604e623e259c3e8677d57f761a3708423fb2e77e2aBryce Lee 1617dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozasp<IBinder> SurfaceControl::getHandle() const 1627dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza{ 1637dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza Mutex::Autolock lock(mLock); 1647dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza return mHandle; 1657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza} 1667dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1674cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carrsp<SurfaceComposerClient> SurfaceControl::getClient() const 1684cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carr{ 1694cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carr return mClient; 1704cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carr} 1714cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carr 172f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggivoid SurfaceControl::writeToParcel(Parcel* parcel) 173f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi{ 174f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient())); 175f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi parcel->writeStrongBinder(mHandle); 176f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer)); 177f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi} 178f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi 179f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggisp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel) 180f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi{ 181f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi sp<IBinder> client = parcel->readStrongBinder(); 182f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi sp<IBinder> handle = parcel->readStrongBinder(); 183f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi if (client == nullptr || handle == nullptr) 184f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi { 185f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi ALOGE("Invalid parcel"); 186f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi return nullptr; 187f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi } 188f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi sp<IBinder> gbp; 189f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi parcel->readNullableStrongBinder(&gbp); 1900b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi 1910b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi // We aren't the original owner of the surface. 192f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi return new SurfaceControl(new SurfaceComposerClient( 193f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi interface_cast<ISurfaceComposerClient>(client)), 1940b26710528eb69f3883f295f3e6146e6466fd082Jorim Jaggi handle.get(), interface_cast<IGraphicBufferProducer>(gbp), false /* owned */); 195f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi} 196f3cf4bcfa2c558f03e178f7044d3cb12fa0e73edJorim Jaggi 197e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian// ---------------------------------------------------------------------------- 198e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian}; // namespace android 199