1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/android/AndroidDirectTexture.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,126 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <unistd.h> 1.10 +#include <errno.h> 1.11 +#include "AndroidDirectTexture.h" 1.12 +#include "nsRect.h" 1.13 + 1.14 +namespace mozilla { 1.15 + 1.16 +AndroidDirectTexture::AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage, 1.17 + gfxImageFormat format) : 1.18 + mLock("AndroidDirectTexture.mLock") 1.19 + , mNeedFlip(false) 1.20 + , mWidth(width) 1.21 + , mHeight(height) 1.22 + , mFormat(format) 1.23 + , mPendingReallocBuffer(nullptr) 1.24 +{ 1.25 + mFrontBuffer = new AndroidGraphicBuffer(width, height, usage, format); 1.26 + mBackBuffer = new AndroidGraphicBuffer(width, height, usage, format); 1.27 +} 1.28 + 1.29 +AndroidDirectTexture::~AndroidDirectTexture() 1.30 +{ 1.31 + if (mFrontBuffer) { 1.32 + delete mFrontBuffer; 1.33 + mFrontBuffer = nullptr; 1.34 + } 1.35 + 1.36 + if (mBackBuffer) { 1.37 + delete mBackBuffer; 1.38 + mBackBuffer = nullptr; 1.39 + } 1.40 +} 1.41 + 1.42 +void 1.43 +AndroidDirectTexture::ReallocPendingBuffer() 1.44 +{ 1.45 + // We may have reallocated while the current back buffer was being 1.46 + // used as the front buffer. If we have such a reallocation pending 1.47 + // and the current back buffer is the target buffer, do it now. 1.48 + // 1.49 + // It is assumed that mLock is already acquired 1.50 + if (mPendingReallocBuffer == mBackBuffer) { 1.51 + mBackBuffer->Reallocate(mWidth, mHeight, mFormat); 1.52 + mPendingReallocBuffer = nullptr; 1.53 + } 1.54 +} 1.55 + 1.56 +bool 1.57 +AndroidDirectTexture::Lock(uint32_t aUsage, unsigned char **bits) 1.58 +{ 1.59 + nsIntRect rect(0, 0, mWidth, mHeight); 1.60 + return Lock(aUsage, rect, bits); 1.61 +} 1.62 + 1.63 +bool 1.64 +AndroidDirectTexture::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits) 1.65 +{ 1.66 + mLock.Lock(); 1.67 + ReallocPendingBuffer(); 1.68 + 1.69 + int result; 1.70 + while ((result = mBackBuffer->Lock(aUsage, aRect, bits)) == -EBUSY) { 1.71 + usleep(1000); // 1ms 1.72 + } 1.73 + 1.74 + return result == 0; 1.75 +} 1.76 + 1.77 +bool 1.78 +AndroidDirectTexture::Unlock(bool aFlip) 1.79 +{ 1.80 + if (aFlip) { 1.81 + mNeedFlip = true; 1.82 + } 1.83 + 1.84 + bool result = mBackBuffer->Unlock(); 1.85 + mLock.Unlock(); 1.86 + 1.87 + return result; 1.88 +} 1.89 + 1.90 +bool 1.91 +AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight) { 1.92 + return Reallocate(aWidth, aHeight, mFormat); 1.93 +} 1.94 + 1.95 +bool 1.96 +AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat) 1.97 +{ 1.98 + MutexAutoLock lock(mLock); 1.99 + 1.100 + // We only reallocate the current back buffer. The front buffer is likely 1.101 + // in use, so we'll reallocate it on the first Lock() after it is rotated 1.102 + // to the back. 1.103 + bool result = mBackBuffer->Reallocate(aWidth, aHeight, aFormat); 1.104 + if (result) { 1.105 + mPendingReallocBuffer = mFrontBuffer; 1.106 + 1.107 + mWidth = aWidth; 1.108 + mHeight = aHeight; 1.109 + } 1.110 + 1.111 + return result; 1.112 +} 1.113 + 1.114 +bool 1.115 +AndroidDirectTexture::Bind() 1.116 +{ 1.117 + MutexAutoLock lock(mLock); 1.118 + 1.119 + if (mNeedFlip) { 1.120 + AndroidGraphicBuffer* tmp = mBackBuffer; 1.121 + mBackBuffer = mFrontBuffer; 1.122 + mFrontBuffer = tmp; 1.123 + mNeedFlip = false; 1.124 + } 1.125 + 1.126 + return mFrontBuffer->Bind(); 1.127 +} 1.128 + 1.129 +} /* mozilla */