1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
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 "mozilla/Preferences.h"
8 #include "SharedSurfaceGralloc.h"
10 #include "GLContext.h"
11 #include "SharedSurfaceGL.h"
12 #include "SurfaceFactory.h"
13 #include "GLLibraryEGL.h"
14 #include "mozilla/layers/GrallocTextureClient.h"
15 #include "mozilla/layers/ShadowLayers.h"
17 #include "ui/GraphicBuffer.h"
18 #include "../layers/ipc/ShadowLayers.h"
19 #include "ScopedGLHelpers.h"
21 #include "gfxPlatform.h"
22 #include "gfx2DGlue.h"
27 #define DEBUG_PRINT(...) do { printf_stderr(__VA_ARGS__); } while (0)
29 #define DEBUG_PRINT(...) do { } while (0)
35 using namespace mozilla::gfx
;
36 using namespace mozilla::layers
;
37 using namespace android
;
39 SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext
* prodGL
,
40 const SurfaceCaps
& caps
,
41 layers::ISurfaceAllocator
* allocator
)
42 : SurfaceFactory_GL(prodGL
, SharedSurfaceType::Gralloc
, caps
)
44 if (caps
.surfaceAllocator
) {
45 allocator
= caps
.surfaceAllocator
;
48 MOZ_ASSERT(allocator
);
50 mAllocator
= allocator
;
53 SharedSurface_Gralloc
*
54 SharedSurface_Gralloc::Create(GLContext
* prodGL
,
55 const GLFormats
& formats
,
56 const gfx::IntSize
& size
,
58 ISurfaceAllocator
* allocator
)
60 GLLibraryEGL
* egl
= &sEGLLibrary
;
63 DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
65 if (!HasExtensions(egl
, prodGL
))
68 gfxContentType type
= hasAlpha
? gfxContentType::COLOR_ALPHA
69 : gfxContentType::COLOR
;
72 = gfxPlatform::GetPlatform()->OptimalFormatForContent(type
);
74 RefPtr
<GrallocTextureClientOGL
> grallocTC
=
75 new GrallocTextureClientOGL(
77 gfx::ImageFormatToSurfaceFormat(format
),
78 gfx::BackendType::NONE
, // we don't need to use it with a DrawTarget
79 layers::TextureFlags::DEFAULT
);
81 if (!grallocTC
->AllocateForGLRendering(size
)) {
85 sp
<GraphicBuffer
> buffer
= grallocTC
->GetGraphicBuffer();
87 EGLDisplay display
= egl
->Display();
88 EGLClientBuffer clientBuffer
= buffer
->getNativeBuffer();
90 LOCAL_EGL_NONE
, LOCAL_EGL_NONE
92 EGLImage image
= egl
->fCreateImage(display
,
94 LOCAL_EGL_NATIVE_BUFFER_ANDROID
,
100 prodGL
->MakeCurrent();
102 prodGL
->fGenTextures(1, &prodTex
);
103 ScopedBindTexture
autoTex(prodGL
, prodTex
);
105 prodGL
->fTexParameteri(LOCAL_GL_TEXTURE_2D
, LOCAL_GL_TEXTURE_MIN_FILTER
, LOCAL_GL_LINEAR
);
106 prodGL
->fTexParameteri(LOCAL_GL_TEXTURE_2D
, LOCAL_GL_TEXTURE_MAG_FILTER
, LOCAL_GL_LINEAR
);
107 prodGL
->fTexParameteri(LOCAL_GL_TEXTURE_2D
, LOCAL_GL_TEXTURE_WRAP_S
, LOCAL_GL_CLAMP_TO_EDGE
);
108 prodGL
->fTexParameteri(LOCAL_GL_TEXTURE_2D
, LOCAL_GL_TEXTURE_WRAP_T
, LOCAL_GL_CLAMP_TO_EDGE
);
110 prodGL
->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D
, image
);
112 egl
->fDestroyImage(display
, image
);
114 SharedSurface_Gralloc
*surf
= new SharedSurface_Gralloc(prodGL
, size
, hasAlpha
, egl
, allocator
, grallocTC
, prodTex
);
116 DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf
, buffer
.get());
122 SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext
* prodGL
,
123 const gfx::IntSize
& size
,
126 layers::ISurfaceAllocator
* allocator
,
127 layers::GrallocTextureClientOGL
* textureClient
,
129 : SharedSurface_GL(SharedSurfaceType::Gralloc
,
130 AttachmentType::GLTexture
,
136 , mAllocator(allocator
)
137 , mTextureClient(textureClient
)
144 SharedSurface_Gralloc::HasExtensions(GLLibraryEGL
* egl
, GLContext
* gl
)
146 return egl
->HasKHRImageBase() &&
147 gl
->IsExtensionSupported(GLContext::OES_EGL_image
);
150 SharedSurface_Gralloc::~SharedSurface_Gralloc()
153 DEBUG_PRINT("[SharedSurface_Gralloc %p] destroyed\n", this);
156 mGL
->fDeleteTextures(1, &mProdTex
);
159 MOZ_ALWAYS_TRUE( mEGL
->fDestroySync(mEGL
->Display(), mSync
) );
165 SharedSurface_Gralloc::Fence()
168 MOZ_ALWAYS_TRUE( mEGL
->fDestroySync(mEGL
->Display(), mSync
) );
172 bool disableSyncFence
= false;
173 // Disable sync fence on AdrenoTM200.
174 // AdrenoTM200's sync fence does not work correctly. See Bug 1022205.
175 if (mGL
->Renderer() == GLRenderer::AdrenoTM200
) {
176 disableSyncFence
= true;
179 // When Android native fences are available, try
180 // them first since they're more likely to work.
181 // Android native fences are also likely to perform better.
182 if (!disableSyncFence
&&
183 mEGL
->IsExtensionSupported(GLLibraryEGL::ANDROID_native_fence_sync
))
186 EGLSync sync
= mEGL
->fCreateSync(mEGL
->Display(),
187 LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID
,
191 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
192 int fenceFd
= mEGL
->fDupNativeFenceFDANDROID(mEGL
->Display(), sync
);
194 mEGL
->fDestroySync(mEGL
->Display(), sync
);
195 android::sp
<android::Fence
> fence(new android::Fence(fenceFd
));
196 FenceHandle handle
= FenceHandle(fence
);
197 mTextureClient
->SetAcquireFenceHandle(handle
);
208 if (!disableSyncFence
&&
209 mEGL
->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync
))
212 mSync
= mEGL
->fCreateSync(mEGL
->Display(),
213 LOCAL_EGL_SYNC_FENCE
,
221 // We should be able to rely on genlock write locks/read locks.
222 // But they're broken on some configs, and even a glFinish doesn't
223 // work. glReadPixels seems to, though.
224 if (gfxPrefs::GrallocFenceWithReadPixels()) {
226 ScopedDeleteArray
<char> buf(new char[4]);
227 mGL
->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
, buf
);
232 SharedSurface_Gralloc::WaitSync()
235 // We must not be needed.
238 MOZ_ASSERT(mEGL
->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync
));
240 EGLint status
= mEGL
->fClientWaitSync(mEGL
->Display(),
245 if (status
!= LOCAL_EGL_CONDITION_SATISFIED
) {
249 MOZ_ALWAYS_TRUE( mEGL
->fDestroySync(mEGL
->Display(), mSync
) );
256 SharedSurface_Gralloc::WaitForBufferOwnership()
258 mTextureClient
->WaitForBufferOwnership();