Bug 1039883 - release Tiled layer's gralloc when an application is background r=nical
[gecko.git] / gfx / layers / opengl / GrallocTextureClient.cpp
blobd8212cfcb78b1b67086a6056daf5b59a00a33654
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 #ifdef MOZ_WIDGET_GONK
8 #include "mozilla/gfx/2D.h"
9 #include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
10 #include "mozilla/layers/GrallocTextureClient.h"
11 #include "mozilla/layers/CompositableForwarder.h"
12 #include "mozilla/layers/ISurfaceAllocator.h"
13 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
14 #include "gfx2DGlue.h"
16 namespace mozilla {
17 namespace layers {
19 using namespace mozilla::gfx;
20 using namespace android;
22 GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
23 gfx::IntSize aSize,
24 gfx::BackendType aMoz2dBackend,
25 TextureFlags aFlags)
26 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags)
27 , mGrallocHandle(buffer)
28 , mMappedBuffer(nullptr)
29 , mMediaBuffer(nullptr)
31 InitWith(buffer, aSize);
32 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
35 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
36 gfx::SurfaceFormat aFormat,
37 gfx::BackendType aMoz2dBackend,
38 TextureFlags aFlags)
39 : BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
40 , mGrallocHandle(null_t())
41 , mMappedBuffer(nullptr)
42 , mMediaBuffer(nullptr)
44 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
47 GrallocTextureClientOGL::~GrallocTextureClientOGL()
49 MOZ_COUNT_DTOR(GrallocTextureClientOGL);
50 ISurfaceAllocator* allocator = GetAllocator();
51 if (ShouldDeallocateInDestructor()) {
52 allocator->DeallocGrallocBuffer(&mGrallocHandle);
53 } else {
54 allocator->DropGrallocBuffer(&mGrallocHandle);
58 void
59 GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle, gfx::IntSize aSize)
61 MOZ_ASSERT(!IsAllocated());
62 MOZ_ASSERT(IsValid());
63 mGrallocHandle = aHandle;
64 mGraphicBuffer = GetGraphicBufferFrom(aHandle);
65 mSize = aSize;
68 bool
69 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
71 MOZ_ASSERT(IsValid());
72 if (!IsAllocated()) {
73 return false;
76 aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mSize);
77 return true;
80 void
81 GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker)
83 mRemoveFromCompositableTracker = aTracker;
86 void
87 GrallocTextureClientOGL::WaitForBufferOwnership()
89 if (mRemoveFromCompositableTracker) {
90 mRemoveFromCompositableTracker->WaitComplete();
91 mRemoveFromCompositableTracker = nullptr;
94 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
95 if (mReleaseFenceHandle.IsValid()) {
96 android::sp<Fence> fence = mReleaseFenceHandle.mFence;
97 #if ANDROID_VERSION == 17
98 fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
99 // 1000 is what Android uses. It is warning timeout ms.
100 // This timeous is removed since ANDROID_VERSION 18.
101 #else
102 fence->waitForever("GrallocTextureClientOGL::Lock");
103 #endif
104 mReleaseFenceHandle = FenceHandle();
106 #endif
109 bool
110 GrallocTextureClientOGL::Lock(OpenMode aMode)
112 MOZ_ASSERT(IsValid());
113 if (!IsValid() || !IsAllocated()) {
114 return false;
117 if (mMappedBuffer) {
118 return true;
121 WaitForBufferOwnership();
123 uint32_t usage = 0;
124 if (aMode & OpenMode::OPEN_READ) {
125 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
127 if (aMode & OpenMode::OPEN_WRITE) {
128 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
130 int32_t rv = mGraphicBuffer->lock(usage, reinterpret_cast<void**>(&mMappedBuffer));
131 if (rv) {
132 mMappedBuffer = nullptr;
133 NS_WARNING("Couldn't lock graphic buffer");
134 return false;
136 return BufferTextureClient::Lock(aMode);
139 void
140 GrallocTextureClientOGL::Unlock()
142 BufferTextureClient::Unlock();
143 mDrawTarget = nullptr;
144 if (mMappedBuffer) {
145 mMappedBuffer = nullptr;
146 mGraphicBuffer->unlock();
150 uint8_t*
151 GrallocTextureClientOGL::GetBuffer() const
153 MOZ_ASSERT(IsValid());
154 NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?");
155 return mMappedBuffer;
158 static gfx::SurfaceFormat
159 SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
161 switch (aFormat) {
162 case PIXEL_FORMAT_RGBA_8888:
163 return gfx::SurfaceFormat::R8G8B8A8;
164 case PIXEL_FORMAT_BGRA_8888:
165 return gfx::SurfaceFormat::B8G8R8A8;
166 case PIXEL_FORMAT_RGBX_8888:
167 return gfx::SurfaceFormat::R8G8B8X8;
168 case PIXEL_FORMAT_RGB_565:
169 return gfx::SurfaceFormat::R5G6B5;
170 default:
171 MOZ_CRASH("Unknown gralloc pixel format");
173 return gfx::SurfaceFormat::R8G8B8A8;
176 gfx::DrawTarget*
177 GrallocTextureClientOGL::BorrowDrawTarget()
179 MOZ_ASSERT(IsValid());
180 MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
182 if (!IsValid() || !IsAllocated()) {
183 return nullptr;
186 if (mDrawTarget) {
187 return mDrawTarget;
190 gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
191 long pixelStride = mGraphicBuffer->getStride();
192 long byteStride = pixelStride * BytesPerPixel(format);
193 mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
194 mSize,
195 byteStride,
196 mFormat);
197 return mDrawTarget;
200 bool
201 GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
202 TextureAllocationFlags)
204 MOZ_ASSERT(IsValid());
206 uint32_t format;
207 uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
208 android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
209 android::GraphicBuffer::USAGE_HW_TEXTURE;
211 switch (mFormat) {
212 case gfx::SurfaceFormat::R8G8B8A8:
213 format = android::PIXEL_FORMAT_RGBA_8888;
214 break;
215 case gfx::SurfaceFormat::B8G8R8A8:
216 format = android::PIXEL_FORMAT_RGBA_8888;
217 mFlags |= TextureFlags::RB_SWAPPED;
218 break;
219 case gfx::SurfaceFormat::R8G8B8X8:
220 format = android::PIXEL_FORMAT_RGBX_8888;
221 break;
222 case gfx::SurfaceFormat::B8G8R8X8:
223 format = android::PIXEL_FORMAT_RGBX_8888;
224 mFlags |= TextureFlags::RB_SWAPPED;
225 break;
226 case gfx::SurfaceFormat::R5G6B5:
227 format = android::PIXEL_FORMAT_RGB_565;
228 break;
229 case gfx::SurfaceFormat::A8:
230 NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
231 return false;
232 default:
233 NS_WARNING("Unsupported surface format");
234 return false;
237 return AllocateGralloc(aSize, format, usage);
240 bool
241 GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode)
243 MOZ_ASSERT(IsValid());
244 return AllocateGralloc(aYSize,
245 HAL_PIXEL_FORMAT_YV12,
246 android::GraphicBuffer::USAGE_SW_READ_OFTEN);
249 bool
250 GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
252 MOZ_ASSERT(IsValid());
254 uint32_t format;
255 uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
256 android::GraphicBuffer::USAGE_HW_TEXTURE;
258 switch (mFormat) {
259 case gfx::SurfaceFormat::R8G8B8A8:
260 case gfx::SurfaceFormat::B8G8R8A8:
261 format = android::PIXEL_FORMAT_RGBA_8888;
262 break;
263 case gfx::SurfaceFormat::R8G8B8X8:
264 case gfx::SurfaceFormat::B8G8R8X8:
265 // there is no android BGRX format?
266 format = android::PIXEL_FORMAT_RGBX_8888;
267 break;
268 case gfx::SurfaceFormat::R5G6B5:
269 format = android::PIXEL_FORMAT_RGB_565;
270 break;
271 default:
272 NS_WARNING("Unsupported surface format");
273 return false;
276 return AllocateGralloc(aSize, format, usage);
279 bool
280 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
281 uint32_t aAndroidFormat,
282 uint32_t aUsage)
284 MOZ_ASSERT(IsValid());
285 ISurfaceAllocator* allocator = GetAllocator();
287 MaybeMagicGrallocBufferHandle handle;
288 bool allocateResult =
289 allocator->AllocGrallocBuffer(aSize,
290 aAndroidFormat,
291 aUsage,
292 &handle);
293 if (!allocateResult) {
294 return false;
297 sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
298 if (!graphicBuffer.get()) {
299 return false;
302 if (graphicBuffer->initCheck() != NO_ERROR) {
303 return false;
306 mGrallocHandle = handle;
307 mGraphicBuffer = graphicBuffer;
308 mSize = aSize;
309 return true;
312 bool
313 GrallocTextureClientOGL::IsAllocated() const
315 return !!mGraphicBuffer.get();
318 bool
319 GrallocTextureClientOGL::Allocate(uint32_t aSize)
321 // see Bug 908196
322 MOZ_CRASH("This method should never be called.");
323 return false;
326 size_t
327 GrallocTextureClientOGL::GetBufferSize() const
329 // see Bug 908196
330 MOZ_CRASH("This method should never be called.");
331 return 0;
334 } // namesapace layers
335 } // namesapace mozilla
337 #endif // MOZ_WIDGET_GONK