gfx/gl/SharedSurfaceGralloc.cpp

changeset 0
6474c204b198
     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 +}

mercurial