summaryrefslogtreecommitdiffstats
path: root/libs/ui/SurfaceComposerClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/SurfaceComposerClient.cpp')
-rw-r--r--libs/ui/SurfaceComposerClient.cpp1026
1 files changed, 0 insertions, 1026 deletions
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
deleted file mode 100644
index 9354a7a..0000000
--- a/libs/ui/SurfaceComposerClient.cpp
+++ /dev/null
@@ -1,1026 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceComposerClient"
-
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <cutils/memory.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-#include <utils/IMemory.h>
-#include <utils/Log.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/ISurface.h>
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-#include <ui/Point.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-#include <private/ui/SurfaceFlingerSynchro.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include <utils/BpBinder.h>
-
-#define VERBOSE(...) ((void)0)
-//#define VERBOSE LOGD
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
-static Mutex gLock;
-static sp<ISurfaceComposer> gSurfaceManager;
-static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
-static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
-static sp<IMemory> gServerCblkMemory;
-static volatile surface_flinger_cblk_t* gServerCblk;
-
-const sp<ISurfaceComposer>& _get_surface_manager()
-{
- if (gSurfaceManager != 0) {
- return gSurfaceManager;
- }
-
- sp<IBinder> binder;
- sp<IServiceManager> sm = defaultServiceManager();
- do {
- binder = sm->getService(String16("SurfaceFlinger"));
- if (binder == 0) {
- LOGW("SurfaceFlinger not published, waiting...");
- usleep(500000); // 0.5 s
- }
- } while(binder == 0);
- sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
-
- Mutex::Autolock _l(gLock);
- if (gSurfaceManager == 0) {
- gSurfaceManager = sc;
- }
- return gSurfaceManager;
-}
-
-static volatile surface_flinger_cblk_t const * get_cblk()
-{
- if (gServerCblk == 0) {
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- Mutex::Autolock _l(gLock);
- if (gServerCblk == 0) {
- gServerCblkMemory = sm->getCblk();
- LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
- gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
- LOGE_IF(gServerCblk==0, "Can't get server control block address");
- }
- }
- return gServerCblk;
-}
-
-// ---------------------------------------------------------------------------
-
-static void copyBlt(const GGLSurface& dst,
- const GGLSurface& src, const Region& reg)
-{
- Region::iterator iterator(reg);
- if (iterator) {
- // NOTE: dst and src must be the same format
- Rect r;
- const size_t bpp = bytesPerPixel(src.format);
- const size_t dbpr = dst.stride * bpp;
- const size_t sbpr = src.stride * bpp;
- while (iterator.iterate(&r)) {
- ssize_t h = r.bottom - r.top;
- if (h) {
- size_t size = (r.right - r.left) * bpp;
- uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
- uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
- if (dbpr==sbpr && size==sbpr) {
- size *= h;
- h = 1;
- }
- do {
- memcpy(d, s, size);
- d += dbpr;
- s += sbpr;
- } while (--h > 0);
- }
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-
-surface_flinger_cblk_t::surface_flinger_cblk_t()
-{
-}
-
-// ---------------------------------------------------------------------------
-
-per_client_cblk_t::per_client_cblk_t()
-{
-}
-
-// these functions are used by the clients
-inline status_t per_client_cblk_t::validate(size_t i) const {
- if (uint32_t(i) >= NUM_LAYERS_MAX)
- return BAD_INDEX;
- if (layers[i].swapState & eInvalidSurface)
- return NO_MEMORY;
- return NO_ERROR;
-}
-
-int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
-{
- int32_t index;
- uint32_t state;
- int timeout = 0;
- status_t result;
- layer_cblk_t * const layer = layers + i;
- const bool blocking = flags & BLOCKING;
- const bool inspect = flags & INSPECT;
-
- do {
- state = layer->swapState;
-
- if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
- LOGE("eNextFlipPending set but eFlipRequested not set, "
- "layer=%d (lcblk=%p), state=%08x",
- int(i), layer, int(state));
- return INVALID_OPERATION;
- }
-
- if (UNLIKELY(state&eLocked)) {
- LOGE("eLocked set when entering lock_layer(), "
- "layer=%d (lcblk=%p), state=%08x",
- int(i), layer, int(state));
- return WOULD_BLOCK;
- }
-
-
- if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
- | eInvalidSurface))
- {
- int32_t resizeIndex;
- Mutex::Autolock _l(lock);
- // might block for a very short amount of time
- // will never cause the server to block (trylock())
-
- goto start_loop_here;
-
- // We block the client if:
- // eNextFlipPending: we've used both buffers already, so we need to
- // wait for one to become availlable.
- // eResizeRequested: the buffer we're going to acquire is being
- // resized. Block until it is done.
- // eFlipRequested && eBusy: the buffer we're going to acquire is
- // currently in use by the server.
- // eInvalidSurface: this is a special case, we don't block in this
- // case, we just return an error.
-
- while((state & (eNextFlipPending|eInvalidSurface)) ||
- (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
- ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
- {
- if (state & eInvalidSurface)
- return NO_MEMORY;
-
- if (!blocking)
- return WOULD_BLOCK;
-
- timeout = 0;
- result = cv.waitRelative(lock, seconds(1));
- if (__builtin_expect(result!=NO_ERROR, false)) {
- const int newState = layer->swapState;
- LOGW( "lock_layer timed out (is the CPU pegged?) "
- "layer=%d, lcblk=%p, state=%08x (was %08x)",
- int(i), layer, newState, int(state));
- timeout = newState != int(state);
- }
-
- start_loop_here:
- state = layer->swapState;
- resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
- }
-
- LOGW_IF(timeout,
- "lock_layer() timed out but didn't appear to need "
- "to be locked and we recovered "
- "(layer=%d, lcblk=%p, state=%08x)",
- int(i), layer, int(state));
- }
-
- // eFlipRequested is not set and cannot be set by another thread: it's
- // safe to use the first buffer without synchronization.
-
- // Choose the index depending on eFlipRequested.
- // When it's set, choose the 'other' buffer.
- index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
-
- // make sure this buffer is valid
- if (layer->surface[index].bits_offset < 0) {
- return status_t(layer->surface[index].bits_offset);
- }
-
- if (inspect) {
- // we just want to inspect this layer. don't lock it.
- goto done;
- }
-
- // last thing before we're done, we need to atomically lock the state
- } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
-
- VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
- int(i), layer, int(index), int(state));
-
- // store the index of the locked buffer (for client use only)
- layer->flags &= ~eBufferIndex;
- layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
-
-done:
- return index;
-}
-
-uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
-{
- // atomically set eFlipRequested and clear eLocked and optionnaly
- // set eNextFlipPending if eFlipRequested was already set
-
- layer_cblk_t * const layer = layers + i;
- int32_t oldvalue, newvalue;
- do {
- oldvalue = layer->swapState;
- // get current value
-
- newvalue = oldvalue & ~eLocked;
- // clear eLocked
-
- newvalue |= eFlipRequested;
- // set eFlipRequested
-
- if (oldvalue & eFlipRequested)
- newvalue |= eNextFlipPending;
- // if eFlipRequested was alread set, set eNextFlipPending
-
- } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
-
- VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
- int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
- int(newvalue));
-
- // from this point, the server can kick in at anytime and use the first
- // buffer, so we cannot use it anymore, and we must use the 'other'
- // buffer instead (or wait if it is not availlable yet, see lock_layer).
-
- return newvalue;
-}
-
-void per_client_cblk_t::unlock_layer(size_t i)
-{
- layer_cblk_t * const layer = layers + i;
- android_atomic_and(~eLocked, &layer->swapState);
-}
-
-// ---------------------------------------------------------------------------
-
-static inline int compare_type( const layer_state_t& lhs,
- const layer_state_t& rhs) {
- if (lhs.surface < rhs.surface) return -1;
- if (lhs.surface > rhs.surface) return 1;
- return 0;
-}
-
-SurfaceComposerClient::SurfaceComposerClient()
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- if (sm == 0) {
- _init(0, 0);
- return;
- }
-
- _init(sm, sm->createConnection());
-
- if (mClient != 0) {
- Mutex::Autolock _l(gLock);
- VERBOSE("Adding client %p to map", this);
- gActiveConnections.add(mClient->asBinder(), this);
- }
-}
-
-SurfaceComposerClient::SurfaceComposerClient(
- const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
-{
- _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
-}
-
-void SurfaceComposerClient::_init(
- const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
-{
- VERBOSE("Creating client %p, conn %p", this, conn.get());
-
- mSignalServer = 0;
- mPrebuiltLayerState = 0;
- mTransactionOpen = 0;
- mStatus = NO_ERROR;
- mControl = 0;
-
- mClient = conn;
- if (mClient == 0) {
- mStatus = NO_INIT;
- return;
- }
-
- mClient->getControlBlocks(&mControlMemory);
- mSignalServer = new SurfaceFlingerSynchro(sm);
- mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
-}
-
-SurfaceComposerClient::~SurfaceComposerClient()
-{
- VERBOSE("Destroying client %p, conn %p", this, mClient.get());
- dispose();
-}
-
-status_t SurfaceComposerClient::initCheck() const
-{
- return mStatus;
-}
-
-status_t SurfaceComposerClient::validateSurface(
- per_client_cblk_t const* cblk, Surface const * surface)
-{
- SurfaceID index = surface->ID();
- if (cblk == 0) {
- LOGE("cblk is null (surface id=%d, identity=%u)",
- index, surface->getIdentity());
- return NO_INIT;
- }
-
- status_t err = cblk->validate(index);
- if (err != NO_ERROR) {
- LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
- index, surface->getIdentity(), err, strerror(-err));
- return err;
- }
-
- if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
- LOGE("using an invalid surface id=%d, identity=%u should be %d",
- index, surface->getIdentity(), cblk->layers[index].identity);
- return NO_INIT;
- }
-
- return NO_ERROR;
-}
-
-sp<IBinder> SurfaceComposerClient::connection() const
-{
- return (mClient != 0) ? mClient->asBinder() : 0;
-}
-
-sp<SurfaceComposerClient>
-SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
-{
- sp<SurfaceComposerClient> client;
-
- { // scope for lock
- Mutex::Autolock _l(gLock);
- client = gActiveConnections.valueFor(conn);
- }
-
- if (client == 0) {
- // Need to make a new client.
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- client = new SurfaceComposerClient(sm, conn);
- if (client != 0 && client->initCheck() == NO_ERROR) {
- Mutex::Autolock _l(gLock);
- gActiveConnections.add(conn, client);
- //LOGD("we have %d connections", gActiveConnections.size());
- } else {
- client.clear();
- }
- }
-
- return client;
-}
-
-void SurfaceComposerClient::dispose()
-{
- // this can be called more than once.
-
- sp<IMemory> controlMemory;
- sp<ISurfaceFlingerClient> client;
- sp<IMemoryHeap> surfaceHeap;
-
- {
- Mutex::Autolock _lg(gLock);
- Mutex::Autolock _lm(mLock);
-
- delete mSignalServer;
- mSignalServer = 0;
-
- if (mClient != 0) {
- client = mClient;
- mClient.clear();
-
- ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
- if (i >= 0 && gActiveConnections.valueAt(i) == this) {
- VERBOSE("Removing client %p from map at %d", this, int(i));
- gActiveConnections.removeItemsAt(i);
- }
- }
-
- delete mPrebuiltLayerState;
- mPrebuiltLayerState = 0;
- controlMemory = mControlMemory;
- surfaceHeap = mSurfaceHeap;
- mControlMemory.clear();
- mSurfaceHeap.clear();
- mControl = 0;
- mStatus = NO_INIT;
- }
-}
-
-status_t SurfaceComposerClient::getDisplayInfo(
- DisplayID dpy, DisplayInfo* info)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
-
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-
- info->w = dcblk->w;
- info->h = dcblk->h;
- info->orientation = dcblk->orientation;
- info->xdpi = dcblk->xdpi;
- info->ydpi = dcblk->ydpi;
- info->fps = dcblk->fps;
- info->density = dcblk->density;
- return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
-}
-
-ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->w;
-}
-
-ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->h;
-}
-
-ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->orientation;
-}
-
-ssize_t SurfaceComposerClient::getNumberOfDisplays()
-{
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- uint32_t connected = cblk->connected;
- int n = 0;
- while (connected) {
- if (connected&1) n++;
- connected >>= 1;
- }
- return n;
-}
-
-sp<Surface> SurfaceComposerClient::createSurface(
- int pid,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
-{
- sp<Surface> result;
- if (mStatus == NO_ERROR) {
- ISurfaceFlingerClient::surface_data_t data;
- sp<ISurface> surface = mClient->createSurface(&data, pid,
- display, w, h, format, flags);
- if (surface != 0) {
- if (uint32_t(data.token) < NUM_LAYERS_MAX) {
- result = new Surface(this, surface, data, w, h, format, flags);
- }
- }
- }
- return result;
-}
-
-status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
-{
- if (mStatus != NO_ERROR)
- return mStatus;
-
- // it's okay to destroy a surface while a transaction is open,
- // (transactions really are a client-side concept)
- // however, this indicates probably a misuse of the API or a bug
- // in the client code.
- LOGW_IF(mTransactionOpen,
- "Destroying surface while a transaction is open. "
- "Client %p: destroying surface %d, mTransactionOpen=%d",
- this, sid, mTransactionOpen);
-
- status_t err = mClient->destroySurface(sid);
- return err;
-}
-
-status_t SurfaceComposerClient::nextBuffer(Surface* surface,
- Surface::SurfaceInfo* info)
-{
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- int32_t backIdx = surface->mBackbufferIndex;
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- const surface_info_t* const front = lcblk->surface + (1-backIdx);
- info->w = front->w;
- info->h = front->h;
- info->format = front->format;
- info->base = surface->heapBase(1-backIdx);
- info->bits = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
- info->bpr = front->bpr;
-
- return 0;
-}
-
-status_t SurfaceComposerClient::lockSurface(
- Surface* surface,
- Surface::SurfaceInfo* other,
- Region* dirty,
- bool blocking)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- int32_t backIdx = cblk->lock_layer(size_t(index),
- per_client_cblk_t::BLOCKING);
- if (backIdx >= 0) {
- surface->mBackbufferIndex = backIdx;
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- const surface_info_t* const back = lcblk->surface + backIdx;
- const surface_info_t* const front = lcblk->surface + (1-backIdx);
- other->w = back->w;
- other->h = back->h;
- other->format = back->format;
- other->base = surface->heapBase(backIdx);
- other->bits = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
- other->bpr = back->bpr;
-
- const Rect bounds(other->w, other->h);
- Region newDirtyRegion;
-
- if (back->flags & surface_info_t::eBufferDirty) {
- /* it is safe to write *back here, because we're guaranteed
- * SurfaceFlinger is not touching it (since it just granted
- * access to us) */
- const_cast<surface_info_t*>(back)->flags &=
- ~surface_info_t::eBufferDirty;
-
- // content is meaningless in this case and the whole surface
- // needs to be redrawn.
-
- newDirtyRegion.set(bounds);
- if (dirty) {
- *dirty = newDirtyRegion;
- }
-
- //if (bytesPerPixel(other->format) == 4) {
- // android_memset32(
- // (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
- //} else {
- // android_memset16( // fill with green
- // (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
- //}
- }
- else
- {
- if (dirty) {
- dirty->andSelf(Region(bounds));
- newDirtyRegion = *dirty;
- } else {
- newDirtyRegion.set(bounds);
- }
-
- Region copyback;
- if (!(lcblk->flags & eNoCopyBack)) {
- const Region previousDirtyRegion(surface->dirtyRegion());
- copyback = previousDirtyRegion.subtract(newDirtyRegion);
- }
-
- if (!copyback.isEmpty()) {
- // copy front to back
- GGLSurface cb;
- cb.version = sizeof(GGLSurface);
- cb.width = back->w;
- cb.height = back->h;
- cb.stride = back->stride;
- cb.data = (GGLubyte*)surface->heapBase(backIdx);
- cb.data += back->bits_offset;
- cb.format = back->format;
-
- GGLSurface t;
- t.version = sizeof(GGLSurface);
- t.width = front->w;
- t.height = front->h;
- t.stride = front->stride;
- t.data = (GGLubyte*)surface->heapBase(1-backIdx);
- t.data += front->bits_offset;
- t.format = front->format;
-
- //const Region copyback(lcblk->region + 1-backIdx);
- copyBlt(cb, t, copyback);
- }
- }
-
- // update dirty region
- surface->setDirtyRegion(newDirtyRegion);
- }
- return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
-}
-
-void SurfaceComposerClient::_signal_server()
-{
- mSignalServer->signal();
-}
-
-void SurfaceComposerClient::_send_dirty_region(
- layer_cblk_t* lcblk, const Region& dirty)
-{
- const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
- flat_region_t* flat_region = lcblk->region + index;
- status_t err = dirty.write(flat_region, sizeof(flat_region_t));
- if (err < NO_ERROR) {
- // region doesn't fit, use the bounds
- const Region reg(dirty.bounds());
- reg.write(flat_region, sizeof(flat_region_t));
- }
-}
-
-status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- Region dirty(surface->dirtyRegion());
- const Rect& swapRect(surface->swapRectangle());
- if (swapRect.isValid()) {
- dirty.set(swapRect);
- }
-
- // transmit the dirty region
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- _send_dirty_region(lcblk, dirty);
- uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
- if (!(newstate & eNextFlipPending))
- _signal_server();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unlockSurface(Surface* surface)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- cblk->unlock_layer(size_t(index));
- return NO_ERROR;
-}
-
-void SurfaceComposerClient::openGlobalTransaction()
-{
- Mutex::Autolock _l(gLock);
-
- if (gOpenTransactions.size()) {
- LOGE("openGlobalTransaction() called more than once. skipping.");
- return;
- }
-
- const size_t N = gActiveConnections.size();
- VERBOSE("openGlobalTransaction (%ld clients)", N);
- for (size_t i=0; i<N; i++) {
- sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
- if (gOpenTransactions.indexOf(client) < 0) {
- if (client->openTransaction() == NO_ERROR) {
- if (gOpenTransactions.add(client) < 0) {
- // Ooops!
- LOGE( "Unable to add a SurfaceComposerClient "
- "to the global transaction set (out of memory?)");
- client->closeTransaction();
- // let it go, it'll fail later when the user
- // tries to do something with the transaction
- }
- } else {
- LOGE("openTransaction on client %p failed", client.get());
- // let it go, it'll fail later when the user
- // tries to do something with the transaction
- }
- }
- }
-}
-
-void SurfaceComposerClient::closeGlobalTransaction()
-{
- gLock.lock();
- SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
- gOpenTransactions.clear();
- gLock.unlock();
-
- const size_t N = clients.size();
- VERBOSE("closeGlobalTransaction (%ld clients)", N);
- if (N == 1) {
- clients[0]->closeTransaction();
- } else {
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- sm->openGlobalTransaction();
- for (size_t i=0; i<N; i++) {
- clients[i]->closeTransaction();
- }
- sm->closeGlobalTransaction();
- }
-}
-
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->freezeDisplay(dpy, flags);
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->unfreezeDisplay(dpy, flags);
-}
-
-int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->setOrientation(dpy, orientation);
-}
-
-status_t SurfaceComposerClient::openTransaction()
-{
- if (mStatus != NO_ERROR)
- return mStatus;
- Mutex::Autolock _l(mLock);
- VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
- this, mTransactionOpen);
- mTransactionOpen++;
- if (mPrebuiltLayerState == 0) {
- mPrebuiltLayerState = new layer_state_t;
- }
- return NO_ERROR;
-}
-
-
-status_t SurfaceComposerClient::closeTransaction()
-{
- if (mStatus != NO_ERROR)
- return mStatus;
-
- Mutex::Autolock _l(mLock);
-
- VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
- this, mTransactionOpen);
-
- if (mTransactionOpen <= 0) {
- LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
- "called more times than openTransaction()",
- this, mTransactionOpen);
- return INVALID_OPERATION;
- }
-
- if (mTransactionOpen >= 2) {
- mTransactionOpen--;
- return NO_ERROR;
- }
-
- mTransactionOpen = 0;
- const ssize_t count = mStates.size();
- if (count) {
- mClient->setState(count, mStates.array());
- mStates.clear();
- }
- return NO_ERROR;
-}
-
-layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
-{
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface.get());
- if (err != NO_ERROR)
- return 0;
-
- // API usage error, do nothing.
- if (mTransactionOpen<=0) {
- LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
- this, int(index), mTransactionOpen);
- return 0;
- }
-
- // use mPrebuiltLayerState just to find out if we already have it
- layer_state_t& dummy = *mPrebuiltLayerState;
- dummy.surface = index;
- ssize_t i = mStates.indexOf(dummy);
- if (i < 0) {
- // we don't have it, add an initialized layer_state to our list
- i = mStates.add(dummy);
- }
- return mStates.editArray() + i;
-}
-
-layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
-{
- layer_state_t* s;
- mLock.lock();
- s = _get_state_l(surface);
- if (!s) mLock.unlock();
- return s;
-}
-
-void SurfaceComposerClient::_unlockLayerState()
-{
- mLock.unlock();
-}
-
-status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::ePositionChanged;
- s->x = x;
- s->y = y;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eSizeChanged;
- s->w = w;
- s->h = h;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eLayerChanged;
- s->z = z;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::hide(Surface* surface)
-{
- return setFlags(surface, ISurfaceComposer::eLayerHidden,
- ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::show(Surface* surface, int32_t)
-{
- return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::freeze(Surface* surface)
-{
- return setFlags(surface, ISurfaceComposer::eLayerFrozen,
- ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(Surface* surface)
-{
- return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::setFlags(Surface* surface,
- uint32_t flags, uint32_t mask)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eVisibilityChanged;
- s->flags &= ~mask;
- s->flags |= (flags & mask);
- s->mask |= mask;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-
-status_t SurfaceComposerClient::setTransparentRegionHint(
- Surface* surface, const Region& transparentRegion)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eTransparentRegionChanged;
- s->transparentRegion = transparentRegion;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eAlphaChanged;
- s->alpha = alpha;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setMatrix(
- Surface* surface,
- float dsdx, float dtdx,
- float dsdy, float dtdy )
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eMatrixChanged;
- layer_state_t::matrix22_t matrix;
- matrix.dsdx = dsdx;
- matrix.dtdx = dtdx;
- matrix.dsdy = dsdy;
- matrix.dtdy = dtdy;
- s->matrix = matrix;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eFreezeTintChanged;
- s->tint = tint;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-}; // namespace android
-