1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/opengl/GrallocTextureClient.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,359 @@ 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 +#ifdef MOZ_WIDGET_GONK 1.10 + 1.11 +#include "mozilla/gfx/2D.h" 1.12 +#include "mozilla/layers/GrallocTextureClient.h" 1.13 +#include "mozilla/layers/CompositableForwarder.h" 1.14 +#include "mozilla/layers/ISurfaceAllocator.h" 1.15 +#include "mozilla/layers/ShadowLayerUtilsGralloc.h" 1.16 +#include "gfx2DGlue.h" 1.17 + 1.18 +namespace mozilla { 1.19 +namespace layers { 1.20 + 1.21 +using namespace mozilla::gfx; 1.22 +using namespace android; 1.23 + 1.24 +class GrallocTextureClientData : public TextureClientData { 1.25 +public: 1.26 + GrallocTextureClientData(GrallocBufferActor* aActor) 1.27 + : mGrallocActor(aActor) 1.28 + { 1.29 + MOZ_COUNT_CTOR(GrallocTextureClientData); 1.30 + } 1.31 + 1.32 + ~GrallocTextureClientData() 1.33 + { 1.34 + MOZ_COUNT_DTOR(GrallocTextureClientData); 1.35 + MOZ_ASSERT(!mGrallocActor); 1.36 + } 1.37 + 1.38 + virtual void DeallocateSharedData(ISurfaceAllocator* allocator) MOZ_OVERRIDE 1.39 + { 1.40 + allocator->DeallocGrallocBuffer(mGrallocActor); 1.41 + mGrallocActor = nullptr; 1.42 + } 1.43 + 1.44 +private: 1.45 + GrallocBufferActor* mGrallocActor; 1.46 +}; 1.47 + 1.48 +TextureClientData* 1.49 +GrallocTextureClientOGL::DropTextureData() 1.50 +{ 1.51 + TextureClientData* result = new GrallocTextureClientData(mGrallocActor); 1.52 + mGrallocActor = nullptr; 1.53 + mGraphicBuffer = nullptr; 1.54 + return result; 1.55 +} 1.56 + 1.57 +GrallocTextureClientOGL::GrallocTextureClientOGL(GrallocBufferActor* aActor, 1.58 + gfx::IntSize aSize, 1.59 + gfx::BackendType aMoz2dBackend, 1.60 + TextureFlags aFlags) 1.61 +: BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags) 1.62 +, mMappedBuffer(nullptr) 1.63 +, mMediaBuffer(nullptr) 1.64 +{ 1.65 + InitWith(aActor, aSize); 1.66 + MOZ_COUNT_CTOR(GrallocTextureClientOGL); 1.67 +} 1.68 + 1.69 +GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator, 1.70 + gfx::SurfaceFormat aFormat, 1.71 + gfx::BackendType aMoz2dBackend, 1.72 + TextureFlags aFlags) 1.73 +: BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags) 1.74 +, mMappedBuffer(nullptr) 1.75 +, mMediaBuffer(nullptr) 1.76 +{ 1.77 + MOZ_COUNT_CTOR(GrallocTextureClientOGL); 1.78 +} 1.79 + 1.80 +GrallocTextureClientOGL::~GrallocTextureClientOGL() 1.81 +{ 1.82 + MOZ_COUNT_DTOR(GrallocTextureClientOGL); 1.83 + if (ShouldDeallocateInDestructor()) { 1.84 + ISurfaceAllocator* allocator = GetAllocator(); 1.85 + allocator->DeallocGrallocBuffer(mGrallocActor); 1.86 + } 1.87 +} 1.88 + 1.89 +void 1.90 +GrallocTextureClientOGL::InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize) 1.91 +{ 1.92 + MOZ_ASSERT(aActor); 1.93 + MOZ_ASSERT(!IsAllocated()); 1.94 + MOZ_ASSERT(IsValid()); 1.95 + mGrallocActor = aActor; 1.96 + mGraphicBuffer = aActor->GetGraphicBuffer(); 1.97 + mSize = aSize; 1.98 +} 1.99 + 1.100 +bool 1.101 +GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) 1.102 +{ 1.103 + MOZ_ASSERT(IsValid()); 1.104 + if (!IsAllocated()) { 1.105 + return false; 1.106 + } 1.107 + 1.108 + aOutDescriptor = NewSurfaceDescriptorGralloc(nullptr, mGrallocActor, mSize); 1.109 + return true; 1.110 +} 1.111 + 1.112 +void 1.113 +GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) 1.114 +{ 1.115 + mReleaseFenceHandle = aReleaseFenceHandle; 1.116 +} 1.117 + 1.118 +void 1.119 +GrallocTextureClientOGL::WaitReleaseFence() 1.120 +{ 1.121 +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 1.122 + if (mReleaseFenceHandle.IsValid()) { 1.123 + android::sp<Fence> fence = mReleaseFenceHandle.mFence; 1.124 +#if ANDROID_VERSION == 17 1.125 + fence->waitForever(1000, "GrallocTextureClientOGL::Lock"); 1.126 + // 1000 is what Android uses. It is warning timeout ms. 1.127 + // This timeous is removed since ANDROID_VERSION 18. 1.128 +#else 1.129 + fence->waitForever("GrallocTextureClientOGL::Lock"); 1.130 +#endif 1.131 + mReleaseFenceHandle = FenceHandle(); 1.132 + } 1.133 +#endif 1.134 +} 1.135 + 1.136 +bool 1.137 +GrallocTextureClientOGL::Lock(OpenMode aMode) 1.138 +{ 1.139 + MOZ_ASSERT(IsValid()); 1.140 + if (!IsValid() || !IsAllocated()) { 1.141 + return false; 1.142 + } 1.143 + 1.144 + if (mMappedBuffer) { 1.145 + return true; 1.146 + } 1.147 + 1.148 + WaitReleaseFence(); 1.149 + 1.150 + uint32_t usage = 0; 1.151 + if (aMode & OPEN_READ) { 1.152 + usage |= GRALLOC_USAGE_SW_READ_OFTEN; 1.153 + } 1.154 + if (aMode & OPEN_WRITE) { 1.155 + usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; 1.156 + } 1.157 + int32_t rv = mGraphicBuffer->lock(usage, reinterpret_cast<void**>(&mMappedBuffer)); 1.158 + if (rv) { 1.159 + mMappedBuffer = nullptr; 1.160 + NS_WARNING("Couldn't lock graphic buffer"); 1.161 + return false; 1.162 + } 1.163 + return BufferTextureClient::Lock(aMode); 1.164 +} 1.165 + 1.166 +void 1.167 +GrallocTextureClientOGL::Unlock() 1.168 +{ 1.169 + BufferTextureClient::Unlock(); 1.170 + mDrawTarget = nullptr; 1.171 + if (mMappedBuffer) { 1.172 + mMappedBuffer = nullptr; 1.173 + mGraphicBuffer->unlock(); 1.174 + } 1.175 +} 1.176 + 1.177 +uint8_t* 1.178 +GrallocTextureClientOGL::GetBuffer() const 1.179 +{ 1.180 + MOZ_ASSERT(IsValid()); 1.181 + NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?"); 1.182 + return mMappedBuffer; 1.183 +} 1.184 + 1.185 +static gfx::SurfaceFormat 1.186 +SurfaceFormatForPixelFormat(android::PixelFormat aFormat) 1.187 +{ 1.188 + switch (aFormat) { 1.189 + case PIXEL_FORMAT_RGBA_8888: 1.190 + return gfx::SurfaceFormat::R8G8B8A8; 1.191 + case PIXEL_FORMAT_BGRA_8888: 1.192 + return gfx::SurfaceFormat::B8G8R8A8; 1.193 + case PIXEL_FORMAT_RGBX_8888: 1.194 + return gfx::SurfaceFormat::R8G8B8X8; 1.195 + case PIXEL_FORMAT_RGB_565: 1.196 + return gfx::SurfaceFormat::R5G6B5; 1.197 + default: 1.198 + MOZ_CRASH("Unknown gralloc pixel format"); 1.199 + } 1.200 + return gfx::SurfaceFormat::R8G8B8A8; 1.201 +} 1.202 + 1.203 +TemporaryRef<gfx::DrawTarget> 1.204 +GrallocTextureClientOGL::GetAsDrawTarget() 1.205 +{ 1.206 + MOZ_ASSERT(IsValid()); 1.207 + MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::GetAsDrawTarget without locking :("); 1.208 + 1.209 + if (mDrawTarget) { 1.210 + return mDrawTarget; 1.211 + } 1.212 + 1.213 + gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat()); 1.214 + long pixelStride = mGraphicBuffer->getStride(); 1.215 + long byteStride = pixelStride * BytesPerPixel(format); 1.216 + mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(), 1.217 + mSize, 1.218 + byteStride, 1.219 + mFormat); 1.220 + return mDrawTarget; 1.221 +} 1.222 + 1.223 +bool 1.224 +GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize, 1.225 + TextureAllocationFlags) 1.226 +{ 1.227 + MOZ_ASSERT(IsValid()); 1.228 + 1.229 + uint32_t format; 1.230 + uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN | 1.231 + android::GraphicBuffer::USAGE_SW_WRITE_OFTEN | 1.232 + android::GraphicBuffer::USAGE_HW_TEXTURE; 1.233 + 1.234 + switch (mFormat) { 1.235 + case gfx::SurfaceFormat::R8G8B8A8: 1.236 + format = android::PIXEL_FORMAT_RGBA_8888; 1.237 + break; 1.238 + case gfx::SurfaceFormat::B8G8R8A8: 1.239 + format = android::PIXEL_FORMAT_RGBA_8888; 1.240 + mFlags |= TEXTURE_RB_SWAPPED; 1.241 + break; 1.242 + case gfx::SurfaceFormat::R8G8B8X8: 1.243 + format = android::PIXEL_FORMAT_RGBX_8888; 1.244 + break; 1.245 + case gfx::SurfaceFormat::B8G8R8X8: 1.246 + format = android::PIXEL_FORMAT_RGBX_8888; 1.247 + mFlags |= TEXTURE_RB_SWAPPED; 1.248 + break; 1.249 + case gfx::SurfaceFormat::R5G6B5: 1.250 + format = android::PIXEL_FORMAT_RGB_565; 1.251 + break; 1.252 + case gfx::SurfaceFormat::A8: 1.253 + NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8"); 1.254 + return false; 1.255 + default: 1.256 + NS_WARNING("Unsupported surface format"); 1.257 + return false; 1.258 + } 1.259 + 1.260 + return AllocateGralloc(aSize, format, usage); 1.261 +} 1.262 + 1.263 +bool 1.264 +GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode) 1.265 +{ 1.266 + MOZ_ASSERT(IsValid()); 1.267 + return AllocateGralloc(aYSize, 1.268 + HAL_PIXEL_FORMAT_YV12, 1.269 + android::GraphicBuffer::USAGE_SW_READ_OFTEN); 1.270 +} 1.271 + 1.272 +bool 1.273 +GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize) 1.274 +{ 1.275 + MOZ_ASSERT(IsValid()); 1.276 + 1.277 + uint32_t format; 1.278 + uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER | 1.279 + android::GraphicBuffer::USAGE_HW_TEXTURE; 1.280 + 1.281 + switch (mFormat) { 1.282 + case gfx::SurfaceFormat::R8G8B8A8: 1.283 + case gfx::SurfaceFormat::B8G8R8A8: 1.284 + format = android::PIXEL_FORMAT_RGBA_8888; 1.285 + break; 1.286 + case gfx::SurfaceFormat::R8G8B8X8: 1.287 + case gfx::SurfaceFormat::B8G8R8X8: 1.288 + // there is no android BGRX format? 1.289 + format = android::PIXEL_FORMAT_RGBX_8888; 1.290 + break; 1.291 + case gfx::SurfaceFormat::R5G6B5: 1.292 + format = android::PIXEL_FORMAT_RGB_565; 1.293 + break; 1.294 + default: 1.295 + NS_WARNING("Unsupported surface format"); 1.296 + return false; 1.297 + } 1.298 + 1.299 + return AllocateGralloc(aSize, format, usage); 1.300 +} 1.301 + 1.302 +bool 1.303 +GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize, 1.304 + uint32_t aAndroidFormat, 1.305 + uint32_t aUsage) 1.306 +{ 1.307 + MOZ_ASSERT(IsValid()); 1.308 + ISurfaceAllocator* allocator = GetAllocator(); 1.309 + 1.310 + MaybeMagicGrallocBufferHandle handle; 1.311 + PGrallocBufferChild* actor = 1.312 + allocator->AllocGrallocBuffer(aSize, 1.313 + aAndroidFormat, 1.314 + aUsage, 1.315 + &handle); 1.316 + if (!actor) { 1.317 + return false; 1.318 + } 1.319 + GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(actor); 1.320 + gba->InitFromHandle(handle.get_MagicGrallocBufferHandle()); 1.321 + 1.322 + sp<GraphicBuffer> graphicBuffer = gba->GetGraphicBuffer(); 1.323 + if (!graphicBuffer.get()) { 1.324 + return false; 1.325 + } 1.326 + 1.327 + if (graphicBuffer->initCheck() != NO_ERROR) { 1.328 + return false; 1.329 + } 1.330 + 1.331 + mGrallocActor = gba; 1.332 + mGraphicBuffer = graphicBuffer; 1.333 + mSize = aSize; 1.334 + return true; 1.335 +} 1.336 + 1.337 +bool 1.338 +GrallocTextureClientOGL::IsAllocated() const 1.339 +{ 1.340 + return !!mGraphicBuffer.get(); 1.341 +} 1.342 + 1.343 +bool 1.344 +GrallocTextureClientOGL::Allocate(uint32_t aSize) 1.345 +{ 1.346 + // see Bug 908196 1.347 + MOZ_CRASH("This method should never be called."); 1.348 + return false; 1.349 +} 1.350 + 1.351 +size_t 1.352 +GrallocTextureClientOGL::GetBufferSize() const 1.353 +{ 1.354 + // see Bug 908196 1.355 + MOZ_CRASH("This method should never be called."); 1.356 + return 0; 1.357 +} 1.358 + 1.359 +} // namesapace layers 1.360 +} // namesapace mozilla 1.361 + 1.362 +#endif // MOZ_WIDGET_GONK