michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include "AndroidDirectTexture.h" michael@0: #include "nsRect.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: AndroidDirectTexture::AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage, michael@0: gfxImageFormat format) : michael@0: mLock("AndroidDirectTexture.mLock") michael@0: , mNeedFlip(false) michael@0: , mWidth(width) michael@0: , mHeight(height) michael@0: , mFormat(format) michael@0: , mPendingReallocBuffer(nullptr) michael@0: { michael@0: mFrontBuffer = new AndroidGraphicBuffer(width, height, usage, format); michael@0: mBackBuffer = new AndroidGraphicBuffer(width, height, usage, format); michael@0: } michael@0: michael@0: AndroidDirectTexture::~AndroidDirectTexture() michael@0: { michael@0: if (mFrontBuffer) { michael@0: delete mFrontBuffer; michael@0: mFrontBuffer = nullptr; michael@0: } michael@0: michael@0: if (mBackBuffer) { michael@0: delete mBackBuffer; michael@0: mBackBuffer = nullptr; michael@0: } michael@0: } michael@0: michael@0: void michael@0: AndroidDirectTexture::ReallocPendingBuffer() michael@0: { michael@0: // We may have reallocated while the current back buffer was being michael@0: // used as the front buffer. If we have such a reallocation pending michael@0: // and the current back buffer is the target buffer, do it now. michael@0: // michael@0: // It is assumed that mLock is already acquired michael@0: if (mPendingReallocBuffer == mBackBuffer) { michael@0: mBackBuffer->Reallocate(mWidth, mHeight, mFormat); michael@0: mPendingReallocBuffer = nullptr; michael@0: } michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Lock(uint32_t aUsage, unsigned char **bits) michael@0: { michael@0: nsIntRect rect(0, 0, mWidth, mHeight); michael@0: return Lock(aUsage, rect, bits); michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits) michael@0: { michael@0: mLock.Lock(); michael@0: ReallocPendingBuffer(); michael@0: michael@0: int result; michael@0: while ((result = mBackBuffer->Lock(aUsage, aRect, bits)) == -EBUSY) { michael@0: usleep(1000); // 1ms michael@0: } michael@0: michael@0: return result == 0; michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Unlock(bool aFlip) michael@0: { michael@0: if (aFlip) { michael@0: mNeedFlip = true; michael@0: } michael@0: michael@0: bool result = mBackBuffer->Unlock(); michael@0: mLock.Unlock(); michael@0: michael@0: return result; michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight) { michael@0: return Reallocate(aWidth, aHeight, mFormat); michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat) michael@0: { michael@0: MutexAutoLock lock(mLock); michael@0: michael@0: // We only reallocate the current back buffer. The front buffer is likely michael@0: // in use, so we'll reallocate it on the first Lock() after it is rotated michael@0: // to the back. michael@0: bool result = mBackBuffer->Reallocate(aWidth, aHeight, aFormat); michael@0: if (result) { michael@0: mPendingReallocBuffer = mFrontBuffer; michael@0: michael@0: mWidth = aWidth; michael@0: mHeight = aHeight; michael@0: } michael@0: michael@0: return result; michael@0: } michael@0: michael@0: bool michael@0: AndroidDirectTexture::Bind() michael@0: { michael@0: MutexAutoLock lock(mLock); michael@0: michael@0: if (mNeedFlip) { michael@0: AndroidGraphicBuffer* tmp = mBackBuffer; michael@0: mBackBuffer = mFrontBuffer; michael@0: mFrontBuffer = tmp; michael@0: mNeedFlip = false; michael@0: } michael@0: michael@0: return mFrontBuffer->Bind(); michael@0: } michael@0: michael@0: } /* mozilla */