diff options
author | 2011-04-12 22:39:53 -0700 | |
---|---|---|
committer | 2011-05-25 14:37:17 -0700 | |
commit | 86ea1f5f521981d075aef56f11693e4f3bc32fdb (patch) | |
tree | 72e1e44513d3e9e204a4fbd2855a079822e949eb /services/input/SpriteController.cpp | |
parent | a6dbfdd3a858aac52cc87f80f91e8eef7d613605 (diff) |
Initial checkin of spot presentation for touchpad gestures. (DO NOT MERGE)
Added a new PointerIcon API (hidden for now) for loading
pointer icons.
Fixed a starvation problem in the native Looper's sendMessage
implementation which caused new messages to be posted ahead
of old messages sent with sendMessageDelayed.
Redesigned the touch pad gestures to be defined in terms of
more fluid finger / spot movements. The objective is to reinforce
the natural mapping between fingers and spots which means there
must not be any discontinuities in spot motion relative to
the fingers.
Removed the SpotController stub and folded its responsibilities
into PointerController.
Change-Id: Ib647dbd7a57a7f30dd9c6e2c260df51d7bbdd18e
Diffstat (limited to 'services/input/SpriteController.cpp')
-rw-r--r-- | services/input/SpriteController.cpp | 162 |
1 files changed, 89 insertions, 73 deletions
diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp index c6d4390fcc92..2fd1f0ab2715 100644 --- a/services/input/SpriteController.cpp +++ b/services/input/SpriteController.cpp @@ -36,6 +36,9 @@ namespace android { SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) : mLooper(looper), mOverlayLayer(overlayLayer) { mHandler = new WeakMessageHandler(this); + + mLocked.transactionNestingCount = 0; + mLocked.deferredSpriteUpdate = false; } SpriteController::~SpriteController() { @@ -51,17 +54,40 @@ sp<Sprite> SpriteController::createSprite() { return new SpriteImpl(this); } +void SpriteController::openTransaction() { + AutoMutex _l(mLock); + + mLocked.transactionNestingCount += 1; +} + +void SpriteController::closeTransaction() { + AutoMutex _l(mLock); + + LOG_ALWAYS_FATAL_IF(mLocked.transactionNestingCount == 0, + "Sprite closeTransaction() called but there is no open sprite transaction"); + + mLocked.transactionNestingCount -= 1; + if (mLocked.transactionNestingCount == 0 && mLocked.deferredSpriteUpdate) { + mLocked.deferredSpriteUpdate = false; + mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES)); + } +} + void SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) { - bool wasEmpty = mInvalidatedSprites.isEmpty(); - mInvalidatedSprites.push(sprite); + bool wasEmpty = mLocked.invalidatedSprites.isEmpty(); + mLocked.invalidatedSprites.push(sprite); if (wasEmpty) { - mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES)); + if (mLocked.transactionNestingCount != 0) { + mLocked.deferredSpriteUpdate = true; + } else { + mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES)); + } } } void SpriteController::disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl) { - bool wasEmpty = mDisposedSurfaces.isEmpty(); - mDisposedSurfaces.push(surfaceControl); + bool wasEmpty = mLocked.disposedSurfaces.isEmpty(); + mLocked.disposedSurfaces.push(surfaceControl); if (wasEmpty) { mLooper->sendMessage(mHandler, Message(MSG_DISPOSE_SURFACES)); } @@ -89,14 +115,14 @@ void SpriteController::doUpdateSprites() { { // acquire lock AutoMutex _l(mLock); - numSprites = mInvalidatedSprites.size(); + numSprites = mLocked.invalidatedSprites.size(); for (size_t i = 0; i < numSprites; i++) { - const sp<SpriteImpl>& sprite = mInvalidatedSprites.itemAt(i); + const sp<SpriteImpl>& sprite = mLocked.invalidatedSprites.itemAt(i); updates.push(SpriteUpdate(sprite, sprite->getStateLocked())); sprite->resetDirtyLocked(); } - mInvalidatedSprites.clear(); + mLocked.invalidatedSprites.clear(); } // release lock // Create missing surfaces. @@ -105,8 +131,8 @@ void SpriteController::doUpdateSprites() { SpriteUpdate& update = updates.editItemAt(i); if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) { - update.state.surfaceWidth = update.state.bitmap.width(); - update.state.surfaceHeight = update.state.bitmap.height(); + update.state.surfaceWidth = update.state.icon.bitmap.width(); + update.state.surfaceHeight = update.state.icon.bitmap.height(); update.state.surfaceDrawn = false; update.state.surfaceVisible = false; update.state.surfaceControl = obtainSurface( @@ -123,8 +149,8 @@ void SpriteController::doUpdateSprites() { SpriteUpdate& update = updates.editItemAt(i); if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) { - int32_t desiredWidth = update.state.bitmap.width(); - int32_t desiredHeight = update.state.bitmap.height(); + int32_t desiredWidth = update.state.icon.bitmap.width(); + int32_t desiredHeight = update.state.icon.bitmap.height(); if (update.state.surfaceWidth < desiredWidth || update.state.surfaceHeight < desiredHeight) { if (!haveGlobalTransaction) { @@ -187,16 +213,16 @@ void SpriteController::doUpdateSprites() { SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); - surfaceCanvas.drawBitmap(update.state.bitmap, 0, 0, &paint); + surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint); - if (surfaceInfo.w > uint32_t(update.state.bitmap.width())) { + if (surfaceInfo.w > uint32_t(update.state.icon.bitmap.width())) { paint.setColor(0); // transparent fill color - surfaceCanvas.drawRectCoords(update.state.bitmap.width(), 0, - surfaceInfo.w, update.state.bitmap.height(), paint); + surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0, + surfaceInfo.w, update.state.icon.bitmap.height(), paint); } - if (surfaceInfo.h > uint32_t(update.state.bitmap.height())) { + if (surfaceInfo.h > uint32_t(update.state.icon.bitmap.height())) { paint.setColor(0); // transparent fill color - surfaceCanvas.drawRectCoords(0, update.state.bitmap.height(), + surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(), surfaceInfo.w, surfaceInfo.h, paint); } @@ -246,8 +272,8 @@ void SpriteController::doUpdateSprites() { && (becomingVisible || (update.state.dirty & (DIRTY_POSITION | DIRTY_HOTSPOT)))) { status = update.state.surfaceControl->setPosition( - update.state.positionX - update.state.hotSpotX, - update.state.positionY - update.state.hotSpotY); + update.state.positionX - update.state.icon.hotSpotX, + update.state.positionY - update.state.icon.hotSpotY); if (status) { LOGE("Error %d setting sprite surface position.", status); } @@ -329,8 +355,10 @@ void SpriteController::doDisposeSurfaces() { // Collect disposed surfaces. Vector<sp<SurfaceControl> > disposedSurfaces; { // acquire lock - disposedSurfaces = mDisposedSurfaces; - mDisposedSurfaces.clear(); + AutoMutex _l(mLock); + + disposedSurfaces = mLocked.disposedSurfaces; + mLocked.disposedSurfaces.clear(); } // release lock // Release the last reference to each surface outside of the lock. @@ -349,7 +377,8 @@ sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface( getpid(), String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888); - if (surfaceControl == NULL) { + if (surfaceControl == NULL || !surfaceControl->isValid() + || !surfaceControl->getSurface()->isValid()) { LOGE("Error creating sprite surface."); return NULL; } @@ -360,7 +389,7 @@ sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height // --- SpriteController::SpriteImpl --- SpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) : - mController(controller), mTransactionNestingCount(0) { + mController(controller) { } SpriteController::SpriteImpl::~SpriteImpl() { @@ -368,27 +397,33 @@ SpriteController::SpriteImpl::~SpriteImpl() { // Let the controller take care of deleting the last reference to sprite // surfaces so that we do not block the caller on an IPC here. - if (mState.surfaceControl != NULL) { - mController->disposeSurfaceLocked(mState.surfaceControl); - mState.surfaceControl.clear(); + if (mLocked.state.surfaceControl != NULL) { + mController->disposeSurfaceLocked(mLocked.state.surfaceControl); + mLocked.state.surfaceControl.clear(); } } -void SpriteController::SpriteImpl::setBitmap(const SkBitmap* bitmap, - float hotSpotX, float hotSpotY) { +void SpriteController::SpriteImpl::setIcon(const SpriteIcon& icon) { AutoMutex _l(mController->mLock); - if (bitmap) { - bitmap->copyTo(&mState.bitmap, SkBitmap::kARGB_8888_Config); + uint32_t dirty; + if (icon.isValid()) { + icon.bitmap.copyTo(&mLocked.state.icon.bitmap, SkBitmap::kARGB_8888_Config); + + if (!mLocked.state.icon.isValid() + || mLocked.state.icon.hotSpotX != icon.hotSpotX + || mLocked.state.icon.hotSpotY != icon.hotSpotY) { + mLocked.state.icon.hotSpotX = icon.hotSpotX; + mLocked.state.icon.hotSpotY = icon.hotSpotY; + dirty = DIRTY_BITMAP | DIRTY_HOTSPOT; + } else { + dirty = DIRTY_BITMAP; + } + } else if (mLocked.state.icon.isValid()) { + mLocked.state.icon.bitmap.reset(); + dirty = DIRTY_BITMAP | DIRTY_HOTSPOT; } else { - mState.bitmap.reset(); - } - - uint32_t dirty = DIRTY_BITMAP; - if (mState.hotSpotX != hotSpotX || mState.hotSpotY != hotSpotY) { - mState.hotSpotX = hotSpotX; - mState.hotSpotY = hotSpotY; - dirty |= DIRTY_HOTSPOT; + return; // setting to invalid icon and already invalid so nothing to do } invalidateLocked(dirty); @@ -397,8 +432,8 @@ void SpriteController::SpriteImpl::setBitmap(const SkBitmap* bitmap, void SpriteController::SpriteImpl::setVisible(bool visible) { AutoMutex _l(mController->mLock); - if (mState.visible != visible) { - mState.visible = visible; + if (mLocked.state.visible != visible) { + mLocked.state.visible = visible; invalidateLocked(DIRTY_VISIBILITY); } } @@ -406,9 +441,9 @@ void SpriteController::SpriteImpl::setVisible(bool visible) { void SpriteController::SpriteImpl::setPosition(float x, float y) { AutoMutex _l(mController->mLock); - if (mState.positionX != x || mState.positionY != y) { - mState.positionX = x; - mState.positionY = y; + if (mLocked.state.positionX != x || mLocked.state.positionY != y) { + mLocked.state.positionX = x; + mLocked.state.positionY = y; invalidateLocked(DIRTY_POSITION); } } @@ -416,8 +451,8 @@ void SpriteController::SpriteImpl::setPosition(float x, float y) { void SpriteController::SpriteImpl::setLayer(int32_t layer) { AutoMutex _l(mController->mLock); - if (mState.layer != layer) { - mState.layer = layer; + if (mLocked.state.layer != layer) { + mLocked.state.layer = layer; invalidateLocked(DIRTY_LAYER); } } @@ -425,8 +460,8 @@ void SpriteController::SpriteImpl::setLayer(int32_t layer) { void SpriteController::SpriteImpl::setAlpha(float alpha) { AutoMutex _l(mController->mLock); - if (mState.alpha != alpha) { - mState.alpha = alpha; + if (mLocked.state.alpha != alpha) { + mLocked.state.alpha = alpha; invalidateLocked(DIRTY_ALPHA); } } @@ -435,38 +470,19 @@ void SpriteController::SpriteImpl::setTransformationMatrix( const SpriteTransformationMatrix& matrix) { AutoMutex _l(mController->mLock); - if (mState.transformationMatrix != matrix) { - mState.transformationMatrix = matrix; + if (mLocked.state.transformationMatrix != matrix) { + mLocked.state.transformationMatrix = matrix; invalidateLocked(DIRTY_TRANSFORMATION_MATRIX); } } -void SpriteController::SpriteImpl::openTransaction() { - AutoMutex _l(mController->mLock); - - mTransactionNestingCount += 1; -} - -void SpriteController::SpriteImpl::closeTransaction() { - AutoMutex _l(mController->mLock); - - LOG_ALWAYS_FATAL_IF(mTransactionNestingCount == 0, - "Sprite closeTransaction() called but there is no open sprite transaction"); +void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) { + bool wasDirty = mLocked.state.dirty; + mLocked.state.dirty |= dirty; - mTransactionNestingCount -= 1; - if (mTransactionNestingCount == 0 && mState.dirty) { + if (!wasDirty) { mController->invalidateSpriteLocked(this); } } -void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) { - if (mTransactionNestingCount > 0) { - bool wasDirty = mState.dirty; - mState.dirty |= dirty; - if (!wasDirty) { - mController->invalidateSpriteLocked(this); - } - } -} - } // namespace android |