SpriteController.cpp revision 5541de9ea3513a12d1ac2ad07e7e04a3aa7741a0
15541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown/* 25541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Copyright (C) 2011 The Android Open Source Project 35541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 45541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 55541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * you may not use this file except in compliance with the License. 65541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * You may obtain a copy of the License at 75541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 85541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 95541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Unless required by applicable law or agreed to in writing, software 115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * See the License for the specific language governing permissions and 145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * limitations under the License. 155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown */ 165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#define LOG_TAG "Sprites" 185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//#define LOG_NDEBUG 0 205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include "SpriteController.h" 225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <cutils/log.h> 245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <utils/String8.h> 255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <SkBitmap.h> 275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <SkCanvas.h> 285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <SkColor.h> 295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <SkPaint.h> 305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <SkXfermode.h> 315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownnamespace android { 335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// --- SpriteController --- 355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff BrownSpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) : 375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mLooper(looper), mOverlayLayer(overlayLayer) { 385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mHandler = new WeakMessageHandler(this); 395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff BrownSpriteController::~SpriteController() { 425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mLooper->removeMessages(mHandler); 435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mSurfaceComposerClient != NULL) { 455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mSurfaceComposerClient->dispose(); 465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mSurfaceComposerClient.clear(); 475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownsp<Sprite> SpriteController::createSprite() { 515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return new SpriteImpl(this); 525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) { 555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool wasEmpty = mInvalidatedSprites.isEmpty(); 565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mInvalidatedSprites.push(sprite); 575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wasEmpty) { 585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES)); 595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl) { 635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool wasEmpty = mDisposedSurfaces.isEmpty(); 645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mDisposedSurfaces.push(surfaceControl); 655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wasEmpty) { 665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mLooper->sendMessage(mHandler, Message(MSG_DISPOSE_SURFACES)); 675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::handleMessage(const Message& message) { 715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown switch (message.what) { 725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown case MSG_UPDATE_SPRITES: 735541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown doUpdateSprites(); 745541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown break; 755541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown case MSG_DISPOSE_SURFACES: 765541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown doDisposeSurfaces(); 775541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown break; 785541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 795541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::doUpdateSprites() { 825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Collect information about sprite updates. 835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Each sprite update record includes a reference to its associated sprite so we can 845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // be certain the sprites will not be deleted while this function runs. Sprites 855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // may invalidate themselves again during this time but we will handle those changes 865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // in the next iteration. 875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown Vector<SpriteUpdate> updates; 885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown size_t numSprites; 895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { // acquire lock 905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mLock); 915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown numSprites = mInvalidatedSprites.size(); 935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 945541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown const sp<SpriteImpl>& sprite = mInvalidatedSprites.itemAt(i); 955541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 965541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown updates.push(SpriteUpdate(sprite, sprite->getStateLocked())); 975541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown sprite->resetDirtyLocked(); 985541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 995541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mInvalidatedSprites.clear(); 1005541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } // release lock 1015541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Create missing surfaces. 1035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool surfaceChanged = false; 1045541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 1055541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SpriteUpdate& update = updates.editItemAt(i); 1065541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1075541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) { 1085541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceWidth = update.state.bitmap.width(); 1095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceHeight = update.state.bitmap.height(); 1105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceDrawn = false; 1115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceVisible = false; 1125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceControl = obtainSurface( 1135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceWidth, update.state.surfaceHeight); 1145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceControl != NULL) { 1155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 1165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Resize sprites if needed, inside a global transaction. 1215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool haveGlobalTransaction = false; 1225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 1235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SpriteUpdate& update = updates.editItemAt(i); 1245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) { 1265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int32_t desiredWidth = update.state.bitmap.width(); 1275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int32_t desiredHeight = update.state.bitmap.height(); 1285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceWidth < desiredWidth 1295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown || update.state.surfaceHeight < desiredHeight) { 1305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (!haveGlobalTransaction) { 1315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SurfaceComposerClient::openGlobalTransaction(); 1325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown haveGlobalTransaction = true; 1335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight); 1365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 1375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d resizing sprite surface from %dx%d to %dx%d", 1385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status, update.state.surfaceWidth, update.state.surfaceHeight, 1395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown desiredWidth, desiredHeight); 1405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 1415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceWidth = desiredWidth; 1425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceHeight = desiredHeight; 1435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceDrawn = false; 1445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 1455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceVisible) { 1475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->hide(); 1485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 1495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d hiding sprite surface after resize.", status); 1505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 1515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceVisible = false; 1525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (haveGlobalTransaction) { 1595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SurfaceComposerClient::closeGlobalTransaction(); 1605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Redraw sprites if needed. 1635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 1645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SpriteUpdate& update = updates.editItemAt(i); 1655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) { 1675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceDrawn = false; 1685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 1695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn 1725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && update.state.wantSurfaceVisible()) { 1735541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown sp<Surface> surface = update.state.surfaceControl->getSurface(); 1745541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown Surface::SurfaceInfo surfaceInfo; 1755541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status_t status = surface->lock(&surfaceInfo); 1765541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 1775541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d locking sprite surface before drawing.", status); 1785541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 1795541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SkBitmap surfaceBitmap; 1805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format); 1815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config, 1825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceInfo.w, surfaceInfo.h, bpr); 1835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceBitmap.setPixels(surfaceInfo.bits); 1845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SkCanvas surfaceCanvas; 1865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceCanvas.setBitmapDevice(surfaceBitmap); 1875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SkPaint paint; 1895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown paint.setXfermodeMode(SkXfermode::kSrc_Mode); 1905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceCanvas.drawBitmap(update.state.bitmap, 0, 0, &paint); 1915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (surfaceInfo.w > uint32_t(update.state.bitmap.width())) { 1935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown paint.setColor(0); // transparent fill color 1945541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceCanvas.drawRectCoords(update.state.bitmap.width(), 0, 1955541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceInfo.w, update.state.bitmap.height(), paint); 1965541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1975541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (surfaceInfo.h > uint32_t(update.state.bitmap.height())) { 1985541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown paint.setColor(0); // transparent fill color 1995541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceCanvas.drawRectCoords(0, update.state.bitmap.height(), 2005541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown surfaceInfo.w, surfaceInfo.h, paint); 2015541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = surface->unlockAndPost(); 2045541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2055541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d unlocking and posting sprite surface after drawing.", status); 2065541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 2075541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceDrawn = true; 2085541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 2095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Set sprite surface properties and make them visible. 2155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool haveTransaction = false; 2165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 2175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown SpriteUpdate& update = updates.editItemAt(i); 2185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible() 2205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && update.state.surfaceDrawn; 2215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible; 2225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible; 2235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden 2245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA 2255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER 2265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) { 2275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status_t status; 2285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (!haveTransaction) { 2295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = mSurfaceComposerClient->openTransaction(); 2305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d opening transation to update sprite surface.", status); 2325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown break; 2335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown haveTransaction = true; 2355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wantSurfaceVisibleAndDrawn 2385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) { 2395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->setAlpha(update.state.alpha); 2405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d setting sprite surface alpha.", status); 2425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wantSurfaceVisibleAndDrawn 2465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && (becomingVisible || (update.state.dirty & (DIRTY_POSITION 2475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown | DIRTY_HOTSPOT)))) { 2485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->setPosition( 2495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.positionX - update.state.hotSpotX, 2505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.positionY - update.state.hotSpotY); 2515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d setting sprite surface position.", status); 2535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wantSurfaceVisibleAndDrawn 2575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && (becomingVisible 2585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) { 2595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->setMatrix( 2605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.transformationMatrix.dsdx, 2615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.transformationMatrix.dtdx, 2625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.transformationMatrix.dsdy, 2635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.transformationMatrix.dtdy); 2645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d setting sprite surface transformation matrix.", status); 2665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int32_t surfaceLayer = mOverlayLayer + update.state.layer; 2705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (wantSurfaceVisibleAndDrawn 2715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) { 2725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->setLayer(surfaceLayer); 2735541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2745541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d setting sprite surface layer.", status); 2755541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2765541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2775541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2785541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (becomingVisible) { 2795541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->show(surfaceLayer); 2805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d showing sprite surface.", status); 2825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 2835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceVisible = true; 2845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 2855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else if (becomingHidden) { 2875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status = update.state.surfaceControl->hide(); 2885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 2895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d hiding sprite surface.", status); 2905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 2915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceVisible = false; 2925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.surfaceChanged = surfaceChanged = true; 2935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2945541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2955541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2965541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2975541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2985541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (haveTransaction) { 2995541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown status_t status = mSurfaceComposerClient->closeTransaction(); 3005541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (status) { 3015541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error %d closing transaction to update sprite surface.", status); 3025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3045541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3055541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // If any surfaces were changed, write back the new surface properties to the sprites. 3065541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (surfaceChanged) { // acquire lock 3075541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mLock); 3085541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown for (size_t i = 0; i < numSprites; i++) { 3105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown const SpriteUpdate& update = updates.itemAt(i); 3115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (update.surfaceChanged) { 3135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.sprite->setSurfaceLocked(update.state.surfaceControl, 3145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceWidth, update.state.surfaceHeight, 3155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown update.state.surfaceDrawn, update.state.surfaceVisible); 3165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } // release lock 3195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Clear the sprite update vector outside the lock. It is very important that 3215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // we do not clear sprite references inside the lock since we could be releasing 3225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // the last remaining reference to the sprite here which would result in the 3235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // sprite being deleted and the lock being reacquired by the sprite destructor 3245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // while already held. 3255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown updates.clear(); 3265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::doDisposeSurfaces() { 3295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Collect disposed surfaces. 3305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown Vector<sp<SurfaceControl> > disposedSurfaces; 3315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { // acquire lock 3325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown disposedSurfaces = mDisposedSurfaces; 3335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mDisposedSurfaces.clear(); 3345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } // release lock 3355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Release the last reference to each surface outside of the lock. 3375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // We don't want the surfaces to be deleted while we are holding our lock. 3385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown disposedSurfaces.clear(); 3395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::ensureSurfaceComposerClient() { 3425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mSurfaceComposerClient == NULL) { 3435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mSurfaceComposerClient = new SurfaceComposerClient(); 3445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownsp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) { 3485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ensureSurfaceComposerClient(); 3495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface( 3515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown getpid(), String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888); 3525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (surfaceControl == NULL) { 3535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOGE("Error creating sprite surface."); 3545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return NULL; 3555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return surfaceControl; 3575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// --- SpriteController::SpriteImpl --- 3615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff BrownSpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) : 3635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mController(controller), mTransactionNestingCount(0) { 3645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff BrownSpriteController::SpriteImpl::~SpriteImpl() { 3675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _m(mController->mLock); 3685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // Let the controller take care of deleting the last reference to sprite 3705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown // surfaces so that we do not block the caller on an IPC here. 3715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.surfaceControl != NULL) { 3725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mController->disposeSurfaceLocked(mState.surfaceControl); 3735541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.surfaceControl.clear(); 3745541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3755541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3765541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3775541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setBitmap(const SkBitmap* bitmap, 3785541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown float hotSpotX, float hotSpotY) { 3795541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 3805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (bitmap) { 3825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bitmap->copyTo(&mState.bitmap, SkBitmap::kARGB_8888_Config); 3835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 3845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.bitmap.reset(); 3855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown uint32_t dirty = DIRTY_BITMAP; 3885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.hotSpotX != hotSpotX || mState.hotSpotY != hotSpotY) { 3895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.hotSpotX = hotSpotX; 3905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.hotSpotY = hotSpotY; 3915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown dirty |= DIRTY_HOTSPOT; 3925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 3935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3945541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(dirty); 3955541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 3965541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 3975541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setVisible(bool visible) { 3985541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 3995541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4005541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.visible != visible) { 4015541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.visible = visible; 4025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(DIRTY_VISIBILITY); 4035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4045541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4055541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4065541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setPosition(float x, float y) { 4075541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4085541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.positionX != x || mState.positionY != y) { 4105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.positionX = x; 4115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.positionY = y; 4125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(DIRTY_POSITION); 4135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setLayer(int32_t layer) { 4175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.layer != layer) { 4205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.layer = layer; 4215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(DIRTY_LAYER); 4225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setAlpha(float alpha) { 4265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.alpha != alpha) { 4295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.alpha = alpha; 4305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(DIRTY_ALPHA); 4315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::setTransformationMatrix( 4355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown const SpriteTransformationMatrix& matrix) { 4365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mState.transformationMatrix != matrix) { 4395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.transformationMatrix = matrix; 4405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown invalidateLocked(DIRTY_TRANSFORMATION_MATRIX); 4415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::openTransaction() { 4455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mTransactionNestingCount += 1; 4485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::closeTransaction() { 4515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AutoMutex _l(mController->mLock); 4525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown LOG_ALWAYS_FATAL_IF(mTransactionNestingCount == 0, 4545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown "Sprite closeTransaction() called but there is no open sprite transaction"); 4555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mTransactionNestingCount -= 1; 4575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mTransactionNestingCount == 0 && mState.dirty) { 4585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mController->invalidateSpriteLocked(this); 4595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) { 4635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (mTransactionNestingCount > 0) { 4645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown bool wasDirty = mState.dirty; 4655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mState.dirty |= dirty; 4665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (!wasDirty) { 4675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown mController->invalidateSpriteLocked(this); 4685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 4705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 4715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 4725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} // namespace android 473