Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}