bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap) { // This lock need to cover the full update since it is possible that queue // will be cleaned up in the middle of this update without the lock. // The Surface Texture will not block us since the readyForUpdate will check // availability of the slots in the queue first. android::Mutex::Autolock lock(m_transferQueueItemLocks); bool ready = readyForUpdate(); TextureUploadType currentUploadType = m_currentUploadType; if (!ready) { ALOGV("Quit bitmap update: not ready! for tile x y %d %d", renderInfo->x, renderInfo->y); return false; } if (currentUploadType == GpuUpload) { // a) Dequeue the Surface Texture and write into the buffer if (!m_ANW.get()) { ALOGV("ERROR: ANW is null"); return false; } if (!GLUtils::updateSharedSurfaceTextureWithBitmap(m_ANW.get(), bitmap)) return false; } // b) After update the Surface Texture, now udpate the transfer queue info. addItemInTransferQueue(renderInfo, currentUploadType, &bitmap); ALOGV("Bitmap updated x, y %d %d, baseTile %p", renderInfo->x, renderInfo->y, renderInfo->baseTile); return true; }
bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap) { m_transferQueueItemLocks.lock(); bool ready = readyForUpdate(); TextureUploadType currentUploadType = m_currentUploadType; m_transferQueueItemLocks.unlock(); if (!ready) { XLOG("Quit bitmap update: not ready! for tile x y %d %d", renderInfo->x, renderInfo->y); return false; } if (currentUploadType == GpuUpload) { // a) Dequeue the Surface Texture and write into the buffer if (!m_ANW.get()) { XLOG("ERROR: ANW is null"); return false; } ANativeWindow_Buffer buffer; if (ANativeWindow_lock(m_ANW.get(), &buffer, 0)) return false; uint8_t* img = (uint8_t*)buffer.bits; int row, col; int bpp = 4; // Now we only deal with RGBA8888 format. int width = TilesManager::instance()->tileWidth(); int height = TilesManager::instance()->tileHeight(); if (!x && !y && bitmap.width() == width && bitmap.height() == height) { bitmap.lockPixels(); uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels()); if (buffer.stride != bitmap.width()) // Copied line by line since we need to handle the offsets and stride. for (row = 0 ; row < bitmap.height(); row ++) { uint8_t* dst = &(img[buffer.stride * row * bpp]); uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]); memcpy(dst, src, bpp * bitmap.width()); } else memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height()); bitmap.unlockPixels(); } else { // TODO: implement the partial invalidate here! XLOG("ERROR: don't expect to get here yet before we support partial inval"); } ANativeWindow_unlockAndPost(m_ANW.get()); } m_transferQueueItemLocks.lock(); // b) After update the Surface Texture, now udpate the transfer queue info. addItemInTransferQueue(renderInfo, currentUploadType, &bitmap); m_transferQueueItemLocks.unlock(); XLOG("Bitmap updated x, y %d %d, baseTile %p", renderInfo->x, renderInfo->y, renderInfo->baseTile); return true; }