1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/gl/SharedSurfaceGralloc.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,155 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */ 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 +#include "mozilla/Preferences.h" 1.10 + 1.11 +#include "SharedSurfaceGralloc.h" 1.12 + 1.13 +#include "GLContext.h" 1.14 +#include "SharedSurfaceGL.h" 1.15 +#include "SurfaceFactory.h" 1.16 +#include "GLLibraryEGL.h" 1.17 +#include "mozilla/layers/GrallocTextureClient.h" 1.18 +#include "mozilla/layers/ShadowLayers.h" 1.19 + 1.20 +#include "ui/GraphicBuffer.h" 1.21 +#include "../layers/ipc/ShadowLayers.h" 1.22 +#include "ScopedGLHelpers.h" 1.23 + 1.24 +#include "gfxPlatform.h" 1.25 +#include "gfx2DGlue.h" 1.26 +#include "gfxPrefs.h" 1.27 + 1.28 +#define DEBUG_GRALLOC 1.29 +#ifdef DEBUG_GRALLOC 1.30 +#define DEBUG_PRINT(...) do { printf_stderr(__VA_ARGS__); } while (0) 1.31 +#else 1.32 +#define DEBUG_PRINT(...) do { } while (0) 1.33 +#endif 1.34 + 1.35 +using namespace mozilla; 1.36 +using namespace mozilla::gfx; 1.37 +using namespace gl; 1.38 +using namespace layers; 1.39 +using namespace android; 1.40 + 1.41 +SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, 1.42 + const SurfaceCaps& caps, 1.43 + layers::ISurfaceAllocator* allocator) 1.44 + : SurfaceFactory_GL(prodGL, SharedSurfaceType::Gralloc, caps) 1.45 +{ 1.46 + if (caps.surfaceAllocator) { 1.47 + allocator = caps.surfaceAllocator; 1.48 + } 1.49 + 1.50 + MOZ_ASSERT(allocator); 1.51 + 1.52 + mAllocator = allocator; 1.53 +} 1.54 + 1.55 +SharedSurface_Gralloc* 1.56 +SharedSurface_Gralloc::Create(GLContext* prodGL, 1.57 + const GLFormats& formats, 1.58 + const gfx::IntSize& size, 1.59 + bool hasAlpha, 1.60 + ISurfaceAllocator* allocator) 1.61 +{ 1.62 + GLLibraryEGL* egl = &sEGLLibrary; 1.63 + MOZ_ASSERT(egl); 1.64 + 1.65 + DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n"); 1.66 + 1.67 + if (!HasExtensions(egl, prodGL)) 1.68 + return nullptr; 1.69 + 1.70 + gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA 1.71 + : gfxContentType::COLOR; 1.72 + 1.73 + gfxImageFormat format 1.74 + = gfxPlatform::GetPlatform()->OptimalFormatForContent(type); 1.75 + 1.76 + RefPtr<GrallocTextureClientOGL> grallocTC = 1.77 + new GrallocTextureClientOGL( 1.78 + allocator, 1.79 + gfx::ImageFormatToSurfaceFormat(format), 1.80 + gfx::BackendType::NONE, // we don't need to use it with a DrawTarget 1.81 + TEXTURE_FLAGS_DEFAULT); 1.82 + 1.83 + if (!grallocTC->AllocateForGLRendering(size)) { 1.84 + return nullptr; 1.85 + } 1.86 + 1.87 + sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer(); 1.88 + 1.89 + EGLDisplay display = egl->Display(); 1.90 + EGLClientBuffer clientBuffer = buffer->getNativeBuffer(); 1.91 + EGLint attrs[] = { 1.92 + LOCAL_EGL_NONE, LOCAL_EGL_NONE 1.93 + }; 1.94 + EGLImage image = egl->fCreateImage(display, 1.95 + EGL_NO_CONTEXT, 1.96 + LOCAL_EGL_NATIVE_BUFFER_ANDROID, 1.97 + clientBuffer, attrs); 1.98 + if (!image) { 1.99 + return nullptr; 1.100 + } 1.101 + 1.102 + prodGL->MakeCurrent(); 1.103 + GLuint prodTex = 0; 1.104 + prodGL->fGenTextures(1, &prodTex); 1.105 + ScopedBindTexture autoTex(prodGL, prodTex); 1.106 + 1.107 + prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR); 1.108 + prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR); 1.109 + prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); 1.110 + prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); 1.111 + 1.112 + prodGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image); 1.113 + 1.114 + egl->fDestroyImage(display, image); 1.115 + 1.116 + SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, grallocTC, prodTex); 1.117 + 1.118 + DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get()); 1.119 + 1.120 + return surf; 1.121 +} 1.122 + 1.123 + 1.124 +bool 1.125 +SharedSurface_Gralloc::HasExtensions(GLLibraryEGL* egl, GLContext* gl) 1.126 +{ 1.127 + return egl->HasKHRImageBase() && 1.128 + gl->IsExtensionSupported(GLContext::OES_EGL_image); 1.129 +} 1.130 + 1.131 +SharedSurface_Gralloc::~SharedSurface_Gralloc() 1.132 +{ 1.133 + 1.134 + DEBUG_PRINT("[SharedSurface_Gralloc %p] destroyed\n", this); 1.135 + 1.136 + mGL->MakeCurrent(); 1.137 + mGL->fDeleteTextures(1, &mProdTex); 1.138 +} 1.139 + 1.140 +void 1.141 +SharedSurface_Gralloc::Fence() 1.142 +{ 1.143 + // We should be able to rely on genlock write locks/read locks. 1.144 + // But they're broken on some configs, and even a glFinish doesn't 1.145 + // work. glReadPixels seems to, though. 1.146 + if (gfxPrefs::GrallocFenceWithReadPixels()) { 1.147 + mGL->MakeCurrent(); 1.148 + // read a 1x1 pixel 1.149 + unsigned char pixels[4]; 1.150 + mGL->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &pixels[0]); 1.151 + } 1.152 +} 1.153 + 1.154 +bool 1.155 +SharedSurface_Gralloc::WaitSync() 1.156 +{ 1.157 + return true; 1.158 +}