summaryrefslogtreecommitdiffstats
path: root/services/input/SpriteController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/input/SpriteController.cpp')
-rw-r--r--services/input/SpriteController.cpp162
1 files changed, 89 insertions, 73 deletions
diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp
index c6d4390..2fd1f0a 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