SpriteController.cpp revision 5541de9ea3513a12d1ac2ad07e7e04a3aa7741a0
170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve/* 270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * Copyright (C) 2011 The Android Open Source Project 370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * 470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * Licensed under the Apache License, Version 2.0 (the "License"); 570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * you may not use this file except in compliance with the License. 670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * You may obtain a copy of the License at 770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * 870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * http://www.apache.org/licenses/LICENSE-2.0 970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * 1070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * Unless required by applicable law or agreed to in writing, software 1170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * distributed under the License is distributed on an "AS IS" BASIS, 1270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * See the License for the specific language governing permissions and 1470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve * limitations under the License. 155b79591450c47920139705712a402251af7eed79Vikram S. Adve */ 16822b4fb896846b87dd11a330ae13f2239329aeefChris Lattner 176e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve#define LOG_TAG "Sprites" 185b79591450c47920139705712a402251af7eed79Vikram S. Adve 1970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve//#define LOG_NDEBUG 0 2070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 215b79591450c47920139705712a402251af7eed79Vikram S. Adve#include "SpriteController.h" 2270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 2370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <cutils/log.h> 2470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <utils/String8.h> 251885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve 2670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <SkBitmap.h> 2770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <SkCanvas.h> 2870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <SkColor.h> 2970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve#include <SkPaint.h> 306a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve#include <SkXfermode.h> 3170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 321885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Advenamespace android { 331885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve 341885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve// --- SpriteController --- 351885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve 361885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. AdveSpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) : 371885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve mLooper(looper), mOverlayLayer(overlayLayer) { 381885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve mHandler = new WeakMessageHandler(this); 391885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve} 401885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve 411885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. AdveSpriteController::~SpriteController() { 421885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve mLooper->removeMessages(mHandler); 4370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 4470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (mSurfaceComposerClient != NULL) { 4570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mSurfaceComposerClient->dispose(); 4670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mSurfaceComposerClient.clear(); 4770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 4845c171ee25619f6650e90fa5e3102d9969fd82b3Ruchira Sasanka} 4970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 506a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advesp<Sprite> SpriteController::createSprite() { 5170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve return new SpriteImpl(this); 52149977b48a02735861697d5b4df1fe5a8592245fVikram S. Adve} 536e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 5470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Advevoid SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) { 5570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve bool wasEmpty = mInvalidatedSprites.isEmpty(); 5670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mInvalidatedSprites.push(sprite); 5770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wasEmpty) { 5870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES)); 5945c171ee25619f6650e90fa5e3102d9969fd82b3Ruchira Sasanka } 6070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 616a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve 6270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Advevoid SpriteController::disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl) { 63149977b48a02735861697d5b4df1fe5a8592245fVikram S. Adve bool wasEmpty = mDisposedSurfaces.isEmpty(); 646e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve mDisposedSurfaces.push(surfaceControl); 6570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wasEmpty) { 6670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mLooper->sendMessage(mHandler, Message(MSG_DISPOSE_SURFACES)); 6770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 6870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 6945c171ee25619f6650e90fa5e3102d9969fd82b3Ruchira Sasanka 7070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Advevoid SpriteController::handleMessage(const Message& message) { 716a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve switch (message.what) { 7270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve case MSG_UPDATE_SPRITES: 73149977b48a02735861697d5b4df1fe5a8592245fVikram S. Adve doUpdateSprites(); 746e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve break; 7570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve case MSG_DISPOSE_SURFACES: 7670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve doDisposeSurfaces(); 7770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve break; 780b03c6a492a0e09049b6c0bd127bd0ede7732aa5Ruchira Sasanka } 7970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 8070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 8170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Advevoid SpriteController::doUpdateSprites() { 8270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Collect information about sprite updates. 8370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Each sprite update record includes a reference to its associated sprite so we can 8470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // be certain the sprites will not be deleted while this function runs. Sprites 8570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // may invalidate themselves again during this time but we will handle those changes 8670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // in the next iteration. 8770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve Vector<SpriteUpdate> updates; 8870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve size_t numSprites; 896a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve { // acquire lock 9070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve AutoMutex _l(mLock); 9170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 9270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve numSprites = mInvalidatedSprites.size(); 9370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve for (size_t i = 0; i < numSprites; i++) { 946a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve const sp<SpriteImpl>& sprite = mInvalidatedSprites.itemAt(i); 956a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve 966a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve updates.push(SpriteUpdate(sprite, sprite->getStateLocked())); 976a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve sprite->resetDirtyLocked(); 986a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve } 996a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve mInvalidatedSprites.clear(); 1006a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve } // release lock 1016a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve 1026a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve // Create missing surfaces. 1036a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve bool surfaceChanged = false; 1046a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve for (size_t i = 0; i < numSprites; i++) { 10570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SpriteUpdate& update = updates.editItemAt(i); 10670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 10770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) { 1086e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceWidth = update.state.bitmap.width(); 1096e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceHeight = update.state.bitmap.height(); 1106e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceDrawn = false; 1116e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceVisible = false; 1126e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceControl = obtainSurface( 1136e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceWidth, update.state.surfaceHeight); 1146e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (update.state.surfaceControl != NULL) { 1156e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 1166e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 1176e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 1186e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 1196e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 1206e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve // Resize sprites if needed, inside a global transaction. 1216e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve bool haveGlobalTransaction = false; 122e6fdb11e1ae823d69e646e76828ccb5d427a9d3aChris Lattner for (size_t i = 0; i < numSprites; i++) { 12370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SpriteUpdate& update = updates.editItemAt(i); 124e6fdb11e1ae823d69e646e76828ccb5d427a9d3aChris Lattner 1256e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) { 1266e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve int32_t desiredWidth = update.state.bitmap.width(); 1276e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve int32_t desiredHeight = update.state.bitmap.height(); 1286e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (update.state.surfaceWidth < desiredWidth 1296e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve || update.state.surfaceHeight < desiredHeight) { 1306e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (!haveGlobalTransaction) { 1316e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve SurfaceComposerClient::openGlobalTransaction(); 1326e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve haveGlobalTransaction = true; 1336e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 1346e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 1356e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight); 1366e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (status) { 1376e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error %d resizing sprite surface from %dx%d to %dx%d", 1386e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve status, update.state.surfaceWidth, update.state.surfaceHeight, 1396e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve desiredWidth, desiredHeight); 1406e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } else { 1416e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceWidth = desiredWidth; 142e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve update.state.surfaceHeight = desiredHeight; 143e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve update.state.surfaceDrawn = false; 144e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 145e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve 146e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve if (update.state.surfaceVisible) { 147e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve status = update.state.surfaceControl->hide(); 148e949da5bb18f89de40b6781237dfe616cba7bfc9Vikram S. Adve if (status) { 1496e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error %d hiding sprite surface after resize.", status); 1506e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } else { 1516e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceVisible = false; 1526e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 153e6fdb11e1ae823d69e646e76828ccb5d427a9d3aChris Lattner } 15470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 15570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 15670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 15770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 15870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (haveGlobalTransaction) { 15970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SurfaceComposerClient::closeGlobalTransaction(); 16070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 16170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 16270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Redraw sprites if needed. 16370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve for (size_t i = 0; i < numSprites; i++) { 16470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SpriteUpdate& update = updates.editItemAt(i); 16570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 16670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) { 16770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.surfaceDrawn = false; 16870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 169c2a2396e17f8fd6c78afd81368d2b80e8cfe6c42Chris Lattner } 170c2a2396e17f8fd6c78afd81368d2b80e8cfe6c42Chris Lattner 17170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn 17270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve && update.state.wantSurfaceVisible()) { 17370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve sp<Surface> surface = update.state.surfaceControl->getSurface(); 17470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve Surface::SurfaceInfo surfaceInfo; 17570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve status_t status = surface->lock(&surfaceInfo); 17670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 17770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d locking sprite surface before drawing.", status); 17870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } else { 17970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SkBitmap surfaceBitmap; 18070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format); 18170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config, 18270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceInfo.w, surfaceInfo.h, bpr); 18370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceBitmap.setPixels(surfaceInfo.bits); 18470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 18570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SkCanvas surfaceCanvas; 18670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceCanvas.setBitmapDevice(surfaceBitmap); 18770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 18870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SkPaint paint; 18970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve paint.setXfermodeMode(SkXfermode::kSrc_Mode); 1906a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve surfaceCanvas.drawBitmap(update.state.bitmap, 0, 0, &paint); 19170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 19270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (surfaceInfo.w > uint32_t(update.state.bitmap.width())) { 19370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve paint.setColor(0); // transparent fill color 19470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceCanvas.drawRectCoords(update.state.bitmap.width(), 0, 1956a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve surfaceInfo.w, update.state.bitmap.height(), paint); 19670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 19770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (surfaceInfo.h > uint32_t(update.state.bitmap.height())) { 19870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve paint.setColor(0); // transparent fill color 19970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve surfaceCanvas.drawRectCoords(0, update.state.bitmap.height(), 2006a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve surfaceInfo.w, surfaceInfo.h, paint); 2016a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve } 20270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 20370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve status = surface->unlockAndPost(); 2046e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (status) { 2056e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error %d unlocking and posting sprite surface after drawing.", status); 2066e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } else { 2076e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.surfaceDrawn = true; 2086e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 2096e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 21070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 21170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 21270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 21370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 21470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Set sprite surface properties and make them visible. 21570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve bool haveTransaction = false; 2165b79591450c47920139705712a402251af7eed79Vikram S. Adve for (size_t i = 0; i < numSprites; i++) { 21770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve SpriteUpdate& update = updates.editItemAt(i); 21870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 21970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible() 2206a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve && update.state.surfaceDrawn; 2216a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible; 22270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible; 22370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden 2246e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA 2256e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER 2266e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) { 2276e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve status_t status; 2286e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (!haveTransaction) { 229b221a763862ccaed46dee3fbf56c384981d84fbdChris Lattner status = mSurfaceComposerClient->openTransaction(); 230b221a763862ccaed46dee3fbf56c384981d84fbdChris Lattner if (status) { 23170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d opening transation to update sprite surface.", status); 23270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve break; 2335b79591450c47920139705712a402251af7eed79Vikram S. Adve } 2345b79591450c47920139705712a402251af7eed79Vikram S. Adve haveTransaction = true; 23570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 23670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 23770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wantSurfaceVisibleAndDrawn 23870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) { 23970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve status = update.state.surfaceControl->setAlpha(update.state.alpha); 24070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 24170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d setting sprite surface alpha.", status); 2426a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve } 24370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 2446a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve 24570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wantSurfaceVisibleAndDrawn 2466a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve && (becomingVisible || (update.state.dirty & (DIRTY_POSITION 2476a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve | DIRTY_HOTSPOT)))) { 2486a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve status = update.state.surfaceControl->setPosition( 24970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.positionX - update.state.hotSpotX, 2506e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve update.state.positionY - update.state.hotSpotY); 2516e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (status) { 2526e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error %d setting sprite surface position.", status); 2536e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 2546e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 2556a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve 25670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wantSurfaceVisibleAndDrawn 25770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve && (becomingVisible 2586a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) { 2596a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve status = update.state.surfaceControl->setMatrix( 2606a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve update.state.transformationMatrix.dsdx, 2616a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve update.state.transformationMatrix.dtdx, 26270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.transformationMatrix.dsdy, 26370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.transformationMatrix.dtdy); 26470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 2656a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve LOGE("Error %d setting sprite surface transformation matrix.", status); 266149977b48a02735861697d5b4df1fe5a8592245fVikram S. Adve } 26770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 268149977b48a02735861697d5b4df1fe5a8592245fVikram S. Adve 26970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve int32_t surfaceLayer = mOverlayLayer + update.state.layer; 27070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (wantSurfaceVisibleAndDrawn 27170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) { 2726a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve status = update.state.surfaceControl->setLayer(surfaceLayer); 27370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 27470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d setting sprite surface layer.", status); 27570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 27670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 27770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 2786a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve if (becomingVisible) { 27970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve status = update.state.surfaceControl->show(surfaceLayer); 28070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 28170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d showing sprite surface.", status); 28270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } else { 28370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.surfaceVisible = true; 28470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 28570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 28670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } else if (becomingHidden) { 28770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve status = update.state.surfaceControl->hide(); 2886a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve if (status) { 28970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve LOGE("Error %d hiding sprite surface.", status); 29070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } else { 29170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.state.surfaceVisible = false; 29270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.surfaceChanged = surfaceChanged = true; 2936a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve } 29470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 29570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 29670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 2976e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 2986e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (haveTransaction) { 2996e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve status_t status = mSurfaceComposerClient->closeTransaction(); 30070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (status) { 3016e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error %d closing transaction to update sprite surface.", status); 3026e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } 30370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 30470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 30570bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // If any surfaces were changed, write back the new surface properties to the sprites. 30670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (surfaceChanged) { // acquire lock 30770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve AutoMutex _l(mLock); 30870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 3096a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve for (size_t i = 0; i < numSprites; i++) { 31070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve const SpriteUpdate& update = updates.itemAt(i); 31170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 31270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (update.surfaceChanged) { 31370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve update.sprite->setSurfaceLocked(update.state.surfaceControl, 3146a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve update.state.surfaceWidth, update.state.surfaceHeight, 3156a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve update.state.surfaceDrawn, update.state.surfaceVisible); 31670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 31770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } 31870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve } // release lock 31970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 32070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Clear the sprite update vector outside the lock. It is very important that 321990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner // we do not clear sprite references inside the lock since we could be releasing 322990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner // the last remaining reference to the sprite here which would result in the 323990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner // sprite being deleted and the lock being reacquired by the sprite destructor 3246e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve // while already held. 3256e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve updates.clear(); 3266e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve} 3276e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3286e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Advevoid SpriteController::doDisposeSurfaces() { 3296e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve // Collect disposed surfaces. 3306e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve Vector<sp<SurfaceControl> > disposedSurfaces; 3316e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve { // acquire lock 332990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner disposedSurfaces = mDisposedSurfaces; 3336e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve mDisposedSurfaces.clear(); 3346e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve } // release lock 3356e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 33670bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Release the last reference to each surface outside of the lock. 337990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner // We don't want the surfaces to be deleted while we are holding our lock. 338990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner disposedSurfaces.clear(); 33970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 34070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 34170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Advevoid SpriteController::ensureSurfaceComposerClient() { 34270bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve if (mSurfaceComposerClient == NULL) { 34370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve mSurfaceComposerClient = new SurfaceComposerClient(); 344990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner } 3456e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve} 3466e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3476e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Advesp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) { 3486e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve ensureSurfaceComposerClient(); 3496e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3506e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface( 3516e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve getpid(), String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888); 3526e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve if (surfaceControl == NULL) { 3536e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve LOGE("Error creating sprite surface."); 3546e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve return NULL; 355990f2a5a1a0b16d0dc07cee486033c0a3864334eChris Lattner } 3566e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve return surfaceControl; 3576e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve} 3586e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3596e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3606e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve// --- SpriteController::SpriteImpl --- 3616e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3626e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. AdveSpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) : 3636e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve mController(controller), mTransactionNestingCount(0) { 3646e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve} 3656e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. Adve 3666e447181928b95902c38ea89e57bc835ecd83cb5Vikram S. AdveSpriteController::SpriteImpl::~SpriteImpl() { 36770bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve AutoMutex _m(mController->mLock); 36870bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 36970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve // Let the controller take care of deleting the last reference to sprite 3705b79591450c47920139705712a402251af7eed79Vikram S. Adve // surfaces so that we do not block the caller on an IPC here. 3715b79591450c47920139705712a402251af7eed79Vikram S. Adve if (mState.surfaceControl != NULL) { 3725b79591450c47920139705712a402251af7eed79Vikram S. Adve mController->disposeSurfaceLocked(mState.surfaceControl); 373ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka mState.surfaceControl.clear(); 374ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka } 375ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka} 376ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka 377ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasankavoid SpriteController::SpriteImpl::setBitmap(const SkBitmap* bitmap, 378ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka float hotSpotX, float hotSpotY) { 379ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka AutoMutex _l(mController->mLock); 380ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka 381ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka if (bitmap) { 382ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka bitmap->copyTo(&mState.bitmap, SkBitmap::kARGB_8888_Config); 383ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka } else { 384ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka mState.bitmap.reset(); 385ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka } 386ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka 387ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka uint32_t dirty = DIRTY_BITMAP; 388ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka if (mState.hotSpotX != hotSpotX || mState.hotSpotY != hotSpotY) { 389ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka mState.hotSpotX = hotSpotX; 390ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka mState.hotSpotY = hotSpotY; 391ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka dirty |= DIRTY_HOTSPOT; 392ed8f674b9a18312886355288ac49f9a2dd5e4e94Ruchira Sasanka } 393 394 invalidateLocked(dirty); 395} 396 397void SpriteController::SpriteImpl::setVisible(bool visible) { 398 AutoMutex _l(mController->mLock); 399 400 if (mState.visible != visible) { 401 mState.visible = visible; 402 invalidateLocked(DIRTY_VISIBILITY); 403 } 404} 405 406void SpriteController::SpriteImpl::setPosition(float x, float y) { 407 AutoMutex _l(mController->mLock); 408 409 if (mState.positionX != x || mState.positionY != y) { 410 mState.positionX = x; 411 mState.positionY = y; 412 invalidateLocked(DIRTY_POSITION); 413 } 414} 415 416void SpriteController::SpriteImpl::setLayer(int32_t layer) { 417 AutoMutex _l(mController->mLock); 418 419 if (mState.layer != layer) { 420 mState.layer = layer; 421 invalidateLocked(DIRTY_LAYER); 422 } 423} 424 425void SpriteController::SpriteImpl::setAlpha(float alpha) { 426 AutoMutex _l(mController->mLock); 427 428 if (mState.alpha != alpha) { 429 mState.alpha = alpha; 430 invalidateLocked(DIRTY_ALPHA); 431 } 432} 433 434void SpriteController::SpriteImpl::setTransformationMatrix( 435 const SpriteTransformationMatrix& matrix) { 436 AutoMutex _l(mController->mLock); 437 438 if (mState.transformationMatrix != matrix) { 439 mState.transformationMatrix = matrix; 440 invalidateLocked(DIRTY_TRANSFORMATION_MATRIX); 441 } 442} 443 444void SpriteController::SpriteImpl::openTransaction() { 445 AutoMutex _l(mController->mLock); 446 447 mTransactionNestingCount += 1; 448} 449 450void SpriteController::SpriteImpl::closeTransaction() { 451 AutoMutex _l(mController->mLock); 452 453 LOG_ALWAYS_FATAL_IF(mTransactionNestingCount == 0, 454 "Sprite closeTransaction() called but there is no open sprite transaction"); 455 456 mTransactionNestingCount -= 1; 457 if (mTransactionNestingCount == 0 && mState.dirty) { 458 mController->invalidateSpriteLocked(this); 459 } 460} 461 462void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) { 463 if (mTransactionNestingCount > 0) { 464 bool wasDirty = mState.dirty; 465 mState.dirty |= dirty; 466 if (!wasDirty) { 467 mController->invalidateSpriteLocked(this); 468 } 469 } 470} 471 472} // namespace android 473