Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <unistd.h>
7 #include <errno.h>
8 #include "AndroidDirectTexture.h"
9 #include "nsRect.h"
11 namespace mozilla {
13 AndroidDirectTexture::AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage,
14 gfxImageFormat format) :
15 mLock("AndroidDirectTexture.mLock")
16 , mNeedFlip(false)
17 , mWidth(width)
18 , mHeight(height)
19 , mFormat(format)
20 , mPendingReallocBuffer(nullptr)
21 {
22 mFrontBuffer = new AndroidGraphicBuffer(width, height, usage, format);
23 mBackBuffer = new AndroidGraphicBuffer(width, height, usage, format);
24 }
26 AndroidDirectTexture::~AndroidDirectTexture()
27 {
28 if (mFrontBuffer) {
29 delete mFrontBuffer;
30 mFrontBuffer = nullptr;
31 }
33 if (mBackBuffer) {
34 delete mBackBuffer;
35 mBackBuffer = nullptr;
36 }
37 }
39 void
40 AndroidDirectTexture::ReallocPendingBuffer()
41 {
42 // We may have reallocated while the current back buffer was being
43 // used as the front buffer. If we have such a reallocation pending
44 // and the current back buffer is the target buffer, do it now.
45 //
46 // It is assumed that mLock is already acquired
47 if (mPendingReallocBuffer == mBackBuffer) {
48 mBackBuffer->Reallocate(mWidth, mHeight, mFormat);
49 mPendingReallocBuffer = nullptr;
50 }
51 }
53 bool
54 AndroidDirectTexture::Lock(uint32_t aUsage, unsigned char **bits)
55 {
56 nsIntRect rect(0, 0, mWidth, mHeight);
57 return Lock(aUsage, rect, bits);
58 }
60 bool
61 AndroidDirectTexture::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits)
62 {
63 mLock.Lock();
64 ReallocPendingBuffer();
66 int result;
67 while ((result = mBackBuffer->Lock(aUsage, aRect, bits)) == -EBUSY) {
68 usleep(1000); // 1ms
69 }
71 return result == 0;
72 }
74 bool
75 AndroidDirectTexture::Unlock(bool aFlip)
76 {
77 if (aFlip) {
78 mNeedFlip = true;
79 }
81 bool result = mBackBuffer->Unlock();
82 mLock.Unlock();
84 return result;
85 }
87 bool
88 AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight) {
89 return Reallocate(aWidth, aHeight, mFormat);
90 }
92 bool
93 AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat)
94 {
95 MutexAutoLock lock(mLock);
97 // We only reallocate the current back buffer. The front buffer is likely
98 // in use, so we'll reallocate it on the first Lock() after it is rotated
99 // to the back.
100 bool result = mBackBuffer->Reallocate(aWidth, aHeight, aFormat);
101 if (result) {
102 mPendingReallocBuffer = mFrontBuffer;
104 mWidth = aWidth;
105 mHeight = aHeight;
106 }
108 return result;
109 }
111 bool
112 AndroidDirectTexture::Bind()
113 {
114 MutexAutoLock lock(mLock);
116 if (mNeedFlip) {
117 AndroidGraphicBuffer* tmp = mBackBuffer;
118 mBackBuffer = mFrontBuffer;
119 mFrontBuffer = tmp;
120 mNeedFlip = false;
121 }
123 return mFrontBuffer->Bind();
124 }
126 } /* mozilla */