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/. */
8 #include "mozilla/gfx/2D.h"
9 #include "mozilla/layers/GrallocTextureClient.h"
10 #include "mozilla/layers/CompositableForwarder.h"
11 #include "mozilla/layers/ISurfaceAllocator.h"
12 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
13 #include "gfx2DGlue.h"
18 using namespace mozilla::gfx
;
19 using namespace android
;
21 GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer
,
23 gfx::BackendType aMoz2dBackend
,
25 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN
, aMoz2dBackend
, aFlags
)
26 , mGrallocHandle(buffer
)
27 , mMappedBuffer(nullptr)
28 , mMediaBuffer(nullptr)
30 InitWith(buffer
, aSize
);
31 MOZ_COUNT_CTOR(GrallocTextureClientOGL
);
34 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator
* aAllocator
,
35 gfx::SurfaceFormat aFormat
,
36 gfx::BackendType aMoz2dBackend
,
38 : BufferTextureClient(aAllocator
, aFormat
, aMoz2dBackend
, aFlags
)
39 , mMappedBuffer(nullptr)
40 , mMediaBuffer(nullptr)
42 MOZ_COUNT_CTOR(GrallocTextureClientOGL
);
45 GrallocTextureClientOGL::~GrallocTextureClientOGL()
47 MOZ_COUNT_DTOR(GrallocTextureClientOGL
);
48 if (ShouldDeallocateInDestructor()) {
49 ISurfaceAllocator
* allocator
= GetAllocator();
50 allocator
->DeallocGrallocBuffer(&mGrallocHandle
);
55 GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle
, gfx::IntSize aSize
)
57 MOZ_ASSERT(!IsAllocated());
58 MOZ_ASSERT(IsValid());
59 mGrallocHandle
= aHandle
;
60 mGraphicBuffer
= GetGraphicBufferFrom(aHandle
);
65 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor
& aOutDescriptor
)
67 MOZ_ASSERT(IsValid());
72 aOutDescriptor
= NewSurfaceDescriptorGralloc(mGrallocHandle
, mSize
);
77 GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle
)
79 mReleaseFenceHandle
= aReleaseFenceHandle
;
83 GrallocTextureClientOGL::WaitReleaseFence()
85 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
86 if (mReleaseFenceHandle
.IsValid()) {
87 android::sp
<Fence
> fence
= mReleaseFenceHandle
.mFence
;
88 #if ANDROID_VERSION == 17
89 fence
->waitForever(1000, "GrallocTextureClientOGL::Lock");
90 // 1000 is what Android uses. It is warning timeout ms.
91 // This timeous is removed since ANDROID_VERSION 18.
93 fence
->waitForever("GrallocTextureClientOGL::Lock");
95 mReleaseFenceHandle
= FenceHandle();
101 GrallocTextureClientOGL::Lock(OpenMode aMode
)
103 MOZ_ASSERT(IsValid());
104 if (!IsValid() || !IsAllocated()) {
115 if (aMode
& OpenMode::OPEN_READ
) {
116 usage
|= GRALLOC_USAGE_SW_READ_OFTEN
;
118 if (aMode
& OpenMode::OPEN_WRITE
) {
119 usage
|= GRALLOC_USAGE_SW_WRITE_OFTEN
;
121 int32_t rv
= mGraphicBuffer
->lock(usage
, reinterpret_cast<void**>(&mMappedBuffer
));
123 mMappedBuffer
= nullptr;
124 NS_WARNING("Couldn't lock graphic buffer");
127 return BufferTextureClient::Lock(aMode
);
131 GrallocTextureClientOGL::Unlock()
133 BufferTextureClient::Unlock();
134 mDrawTarget
= nullptr;
136 mMappedBuffer
= nullptr;
137 mGraphicBuffer
->unlock();
142 GrallocTextureClientOGL::GetBuffer() const
144 MOZ_ASSERT(IsValid());
145 NS_WARN_IF_FALSE(mMappedBuffer
, "Trying to get a gralloc buffer without getting the lock?");
146 return mMappedBuffer
;
149 static gfx::SurfaceFormat
150 SurfaceFormatForPixelFormat(android::PixelFormat aFormat
)
153 case PIXEL_FORMAT_RGBA_8888
:
154 return gfx::SurfaceFormat::R8G8B8A8
;
155 case PIXEL_FORMAT_BGRA_8888
:
156 return gfx::SurfaceFormat::B8G8R8A8
;
157 case PIXEL_FORMAT_RGBX_8888
:
158 return gfx::SurfaceFormat::R8G8B8X8
;
159 case PIXEL_FORMAT_RGB_565
:
160 return gfx::SurfaceFormat::R5G6B5
;
162 MOZ_CRASH("Unknown gralloc pixel format");
164 return gfx::SurfaceFormat::R8G8B8A8
;
167 TemporaryRef
<gfx::DrawTarget
>
168 GrallocTextureClientOGL::GetAsDrawTarget()
170 MOZ_ASSERT(IsValid());
171 MOZ_ASSERT(mMappedBuffer
, "Calling TextureClient::GetAsDrawTarget without locking :(");
177 gfx::SurfaceFormat format
= SurfaceFormatForPixelFormat(mGraphicBuffer
->getPixelFormat());
178 long pixelStride
= mGraphicBuffer
->getStride();
179 long byteStride
= pixelStride
* BytesPerPixel(format
);
180 mDrawTarget
= gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
188 GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize
,
189 TextureAllocationFlags
)
191 MOZ_ASSERT(IsValid());
194 uint32_t usage
= android::GraphicBuffer::USAGE_SW_READ_OFTEN
|
195 android::GraphicBuffer::USAGE_SW_WRITE_OFTEN
|
196 android::GraphicBuffer::USAGE_HW_TEXTURE
;
199 case gfx::SurfaceFormat::R8G8B8A8
:
200 format
= android::PIXEL_FORMAT_RGBA_8888
;
202 case gfx::SurfaceFormat::B8G8R8A8
:
203 format
= android::PIXEL_FORMAT_RGBA_8888
;
204 mFlags
|= TextureFlags::RB_SWAPPED
;
206 case gfx::SurfaceFormat::R8G8B8X8
:
207 format
= android::PIXEL_FORMAT_RGBX_8888
;
209 case gfx::SurfaceFormat::B8G8R8X8
:
210 format
= android::PIXEL_FORMAT_RGBX_8888
;
211 mFlags
|= TextureFlags::RB_SWAPPED
;
213 case gfx::SurfaceFormat::R5G6B5
:
214 format
= android::PIXEL_FORMAT_RGB_565
;
216 case gfx::SurfaceFormat::A8
:
217 NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
220 NS_WARNING("Unsupported surface format");
224 return AllocateGralloc(aSize
, format
, usage
);
228 GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize
, gfx::IntSize aCbCrSize
, StereoMode aStereoMode
)
230 MOZ_ASSERT(IsValid());
231 return AllocateGralloc(aYSize
,
232 HAL_PIXEL_FORMAT_YV12
,
233 android::GraphicBuffer::USAGE_SW_READ_OFTEN
);
237 GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize
)
239 MOZ_ASSERT(IsValid());
242 uint32_t usage
= android::GraphicBuffer::USAGE_HW_RENDER
|
243 android::GraphicBuffer::USAGE_HW_TEXTURE
;
246 case gfx::SurfaceFormat::R8G8B8A8
:
247 case gfx::SurfaceFormat::B8G8R8A8
:
248 format
= android::PIXEL_FORMAT_RGBA_8888
;
250 case gfx::SurfaceFormat::R8G8B8X8
:
251 case gfx::SurfaceFormat::B8G8R8X8
:
252 // there is no android BGRX format?
253 format
= android::PIXEL_FORMAT_RGBX_8888
;
255 case gfx::SurfaceFormat::R5G6B5
:
256 format
= android::PIXEL_FORMAT_RGB_565
;
259 NS_WARNING("Unsupported surface format");
263 return AllocateGralloc(aSize
, format
, usage
);
267 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize
,
268 uint32_t aAndroidFormat
,
271 MOZ_ASSERT(IsValid());
272 ISurfaceAllocator
* allocator
= GetAllocator();
274 MaybeMagicGrallocBufferHandle handle
;
275 bool allocateResult
=
276 allocator
->AllocGrallocBuffer(aSize
,
280 if (!allocateResult
) {
284 sp
<GraphicBuffer
> graphicBuffer
= GetGraphicBufferFrom(handle
);
285 if (!graphicBuffer
.get()) {
289 if (graphicBuffer
->initCheck() != NO_ERROR
) {
293 mGrallocHandle
= handle
;
294 mGraphicBuffer
= graphicBuffer
;
300 GrallocTextureClientOGL::IsAllocated() const
302 return !!mGraphicBuffer
.get();
306 GrallocTextureClientOGL::Allocate(uint32_t aSize
)
309 MOZ_CRASH("This method should never be called.");
314 GrallocTextureClientOGL::GetBufferSize() const
317 MOZ_CRASH("This method should never be called.");
321 } // namesapace layers
322 } // namesapace mozilla
324 #endif // MOZ_WIDGET_GONK