Surface.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
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 "Surface" 18 19#include <stdint.h> 20#include <unistd.h> 21#include <fcntl.h> 22#include <errno.h> 23#include <sys/types.h> 24#include <sys/stat.h> 25 26#include <utils/Atomic.h> 27#include <utils/Errors.h> 28#include <utils/threads.h> 29#include <utils/IPCThreadState.h> 30#include <utils/IMemory.h> 31#include <utils/Log.h> 32 33#include <ui/ISurface.h> 34#include <ui/Surface.h> 35#include <ui/SurfaceComposerClient.h> 36#include <ui/Rect.h> 37 38#include <private/ui/SharedState.h> 39#include <private/ui/LayerState.h> 40 41namespace android { 42 43// --------------------------------------------------------------------------- 44 45Surface::Surface(const sp<SurfaceComposerClient>& client, 46 const sp<ISurface>& surface, 47 const ISurfaceFlingerClient::surface_data_t& data, 48 uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 49 bool owner) 50 : mClient(client), mSurface(surface), 51 mToken(data.token), mIdentity(data.identity), 52 mFormat(format), mFlags(flags), mOwner(owner) 53{ 54 mSwapRectangle.makeInvalid(); 55 mSurfaceHeapBase[0] = 0; 56 mSurfaceHeapBase[1] = 0; 57 mHeap[0] = data.heap[0]; 58 mHeap[1] = data.heap[1]; 59} 60 61Surface::Surface(Surface const* rhs) 62 : mOwner(false) 63{ 64 mToken = rhs->mToken; 65 mIdentity= rhs->mIdentity; 66 mClient = rhs->mClient; 67 mSurface = rhs->mSurface; 68 mHeap[0] = rhs->mHeap[0]; 69 mHeap[1] = rhs->mHeap[1]; 70 mFormat = rhs->mFormat; 71 mFlags = rhs->mFlags; 72 mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0]; 73 mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1]; 74 mSwapRectangle.makeInvalid(); 75} 76 77Surface::~Surface() 78{ 79 if (mOwner && mToken>=0 && mClient!=0) { 80 mClient->destroySurface(mToken); 81 } 82 mClient.clear(); 83 mSurface.clear(); 84 mHeap[0].clear(); 85 mHeap[1].clear(); 86 IPCThreadState::self()->flushCommands(); 87} 88 89sp<Surface> Surface::dup() const 90{ 91 Surface const * r = this; 92 if (this && mOwner) { 93 // the only reason we need to do this is because of Java's garbage 94 // collector: because we're creating a copy of the Surface 95 // instead of a reference, we can garantee that when our last 96 // reference goes away, the real surface will be deleted. 97 // Without this hack (the code is correct too), we'd have to 98 // wait for a GC for the surface to go away. 99 r = new Surface(this); 100 } 101 return const_cast<Surface*>(r); 102} 103 104status_t Surface::nextBuffer(SurfaceInfo* info) { 105 return mClient->nextBuffer(this, info); 106} 107 108status_t Surface::lock(SurfaceInfo* info, bool blocking) { 109 return Surface::lock(info, NULL, blocking); 110} 111 112status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) { 113 if (heapBase(0) == 0) return INVALID_OPERATION; 114 if (heapBase(1) == 0) return INVALID_OPERATION; 115 return mClient->lockSurface(this, info, dirty, blocking); 116} 117 118status_t Surface::unlockAndPost() { 119 if (heapBase(0) == 0) return INVALID_OPERATION; 120 if (heapBase(1) == 0) return INVALID_OPERATION; 121 return mClient->unlockAndPostSurface(this); 122} 123 124status_t Surface::unlock() { 125 if (heapBase(0) == 0) return INVALID_OPERATION; 126 if (heapBase(1) == 0) return INVALID_OPERATION; 127 return mClient->unlockSurface(this); 128} 129 130status_t Surface::setLayer(int32_t layer) { 131 return mClient->setLayer(this, layer); 132} 133status_t Surface::setPosition(int32_t x, int32_t y) { 134 return mClient->setPosition(this, x, y); 135} 136status_t Surface::setSize(uint32_t w, uint32_t h) { 137 return mClient->setSize(this, w, h); 138} 139status_t Surface::hide() { 140 return mClient->hide(this); 141} 142status_t Surface::show(int32_t layer) { 143 return mClient->show(this, layer); 144} 145status_t Surface::freeze() { 146 return mClient->freeze(this); 147} 148status_t Surface::unfreeze() { 149 return mClient->unfreeze(this); 150} 151status_t Surface::setFlags(uint32_t flags, uint32_t mask) { 152 return mClient->setFlags(this, flags, mask); 153} 154status_t Surface::setTransparentRegionHint(const Region& transparent) { 155 return mClient->setTransparentRegionHint(this, transparent); 156} 157status_t Surface::setAlpha(float alpha) { 158 return mClient->setAlpha(this, alpha); 159} 160status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 161 return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy); 162} 163status_t Surface::setFreezeTint(uint32_t tint) { 164 return mClient->setFreezeTint(this, tint); 165} 166 167Region Surface::dirtyRegion() const { 168 return mDirtyRegion; 169} 170void Surface::setDirtyRegion(const Region& region) const { 171 mDirtyRegion = region; 172} 173const Rect& Surface::swapRectangle() const { 174 return mSwapRectangle; 175} 176void Surface::setSwapRectangle(const Rect& r) { 177 mSwapRectangle = r; 178} 179 180sp<Surface> Surface::readFromParcel(Parcel* parcel) 181{ 182 sp<SurfaceComposerClient> client; 183 ISurfaceFlingerClient::surface_data_t data; 184 sp<IBinder> clientBinder= parcel->readStrongBinder(); 185 sp<ISurface> surface = interface_cast<ISurface>(parcel->readStrongBinder()); 186 data.heap[0] = interface_cast<IMemoryHeap>(parcel->readStrongBinder()); 187 data.heap[1] = interface_cast<IMemoryHeap>(parcel->readStrongBinder()); 188 data.token = parcel->readInt32(); 189 data.identity = parcel->readInt32(); 190 PixelFormat format = parcel->readInt32(); 191 uint32_t flags = parcel->readInt32(); 192 193 if (clientBinder != NULL) 194 client = SurfaceComposerClient::clientForConnection(clientBinder); 195 196 return new Surface(client, surface, data, 0, 0, format, flags, false); 197} 198 199status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel) 200{ 201 uint32_t flags=0; 202 uint32_t format=0; 203 SurfaceID token = -1; 204 uint32_t identity = 0; 205 sp<SurfaceComposerClient> client; 206 sp<ISurface> sur; 207 sp<IMemoryHeap> heap[2]; 208 if (surface->isValid()) { 209 token = surface->mToken; 210 identity = surface->mIdentity; 211 client = surface->mClient; 212 sur = surface->mSurface; 213 heap[0] = surface->mHeap[0]; 214 heap[1] = surface->mHeap[1]; 215 format = surface->mFormat; 216 flags = surface->mFlags; 217 } 218 parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); 219 parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 220 parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL); 221 parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL); 222 parcel->writeInt32(token); 223 parcel->writeInt32(identity); 224 parcel->writeInt32(format); 225 parcel->writeInt32(flags); 226 return NO_ERROR; 227} 228 229bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) 230{ 231 if (lhs == 0 || rhs == 0) 232 return false; 233 return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 234} 235 236void* Surface::heapBase(int i) const 237{ 238 void* heapBase = mSurfaceHeapBase[i]; 239 // map lazily so it doesn't get mapped in clients that don't need it 240 if (heapBase == 0) { 241 const sp<IMemoryHeap>& heap(mHeap[i]); 242 if (heap != 0) { 243 heapBase = static_cast<uint8_t*>(heap->base()); 244 if (heapBase == MAP_FAILED) { 245 heapBase = NULL; 246 LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)", 247 heap->asBinder().get(), heap.get()); 248 } 249 mSurfaceHeapBase[i] = heapBase; 250 } 251 } 252 return heapBase; 253} 254 255}; // namespace android 256 257