зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1191042 - Use CreateOffscreen for WebGL instead of CreateHeadless. - r=jrmuizel
This commit is contained in:
Родитель
59b6510302
Коммит
187dfafc29
|
@ -217,6 +217,7 @@ WebGLContext::WebGLContext()
|
|||
, mBypassShaderValidation(false)
|
||||
, mGLMaxSamples(1)
|
||||
, mNeedsFakeNoAlpha(false)
|
||||
, mNeedsFakeNoDepth(false)
|
||||
, mNeedsFakeNoStencil(false)
|
||||
{
|
||||
mGeneration = 0;
|
||||
|
@ -253,6 +254,7 @@ WebGLContext::WebGLContext()
|
|||
mDitherEnabled = 1;
|
||||
mRasterizerDiscardEnabled = 0; // OpenGL ES 3.0 spec p244
|
||||
mScissorTestEnabled = 0;
|
||||
mDepthTestEnabled = 0;
|
||||
mStencilTestEnabled = 0;
|
||||
|
||||
// initialize some GL values: we're going to get them from the GL and use them as the sizes of arrays,
|
||||
|
@ -543,107 +545,9 @@ HasAcceleratedLayers(const nsCOMPtr<nsIGfxInfo>& gfxInfo)
|
|||
return false;
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessNativeGL(CreateContextFlags flags, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
if (!(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE) &&
|
||||
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
|
||||
{
|
||||
webgl->GenerateWarning("Refused to create native OpenGL context"
|
||||
" because of blacklisting.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless(flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during native OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(!gl->IsANGLE());
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
// Note that we have a separate call for ANGLE and EGL, even though
|
||||
// right now, we get ANGLE implicitly by using EGL on Windows.
|
||||
// Eventually, we want to be able to pick ANGLE-EGL or native EGL.
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessANGLE(CreateContextFlags flags, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
#ifdef XP_WIN
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during ANGLE OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(gl->IsANGLE());
|
||||
#endif
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessEGL(CreateContextFlags flags, WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
#ifdef ANDROID
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during EGL OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(!gl->IsANGLE());
|
||||
#endif
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessGL(CreateContextFlags flags, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL");
|
||||
bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false);
|
||||
|
||||
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
|
||||
disableANGLE = true;
|
||||
|
||||
if (!webgl->IsWebGL2()) {
|
||||
flags |= CreateContextFlags::REQUIRE_COMPAT_PROFILE;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
if (preferEGL)
|
||||
gl = CreateHeadlessEGL(flags, webgl);
|
||||
|
||||
if (!gl && !disableANGLE) {
|
||||
gl = CreateHeadlessANGLE(flags, gfxInfo, webgl);
|
||||
}
|
||||
|
||||
if (!gl) {
|
||||
gl = CreateHeadlessNativeGL(flags, gfxInfo, webgl);
|
||||
}
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
// Try to create a dummy offscreen with the given caps.
|
||||
static bool
|
||||
CreateOffscreenWithCaps(GLContext* gl, const SurfaceCaps& caps)
|
||||
{
|
||||
gfx::IntSize dummySize(16, 16);
|
||||
return gl->InitOffscreen(dummySize, caps);
|
||||
}
|
||||
|
||||
static void
|
||||
PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
|
||||
std::queue<SurfaceCaps>* out_fallbackCaps)
|
||||
PopulateCapFallbackQueue(const gl::SurfaceCaps& baseCaps,
|
||||
std::queue<gl::SurfaceCaps>* out_fallbackCaps)
|
||||
{
|
||||
out_fallbackCaps->push(baseCaps);
|
||||
|
||||
|
@ -651,7 +555,7 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
|
|||
// The user basically doesn't have to handle if this fails, they
|
||||
// just get reduced quality.
|
||||
if (baseCaps.antialias) {
|
||||
SurfaceCaps nextCaps(baseCaps);
|
||||
gl::SurfaceCaps nextCaps(baseCaps);
|
||||
nextCaps.antialias = false;
|
||||
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
|
||||
}
|
||||
|
@ -660,25 +564,22 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
|
|||
// depth. However, the client app will need to handle if this
|
||||
// doesn't work.
|
||||
if (baseCaps.stencil) {
|
||||
SurfaceCaps nextCaps(baseCaps);
|
||||
gl::SurfaceCaps nextCaps(baseCaps);
|
||||
nextCaps.stencil = false;
|
||||
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
|
||||
}
|
||||
|
||||
if (baseCaps.depth) {
|
||||
SurfaceCaps nextCaps(baseCaps);
|
||||
gl::SurfaceCaps nextCaps(baseCaps);
|
||||
nextCaps.depth = false;
|
||||
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
|
||||
const nsCOMPtr<nsIGfxInfo>& gfxInfo, WebGLContext* webgl,
|
||||
layers::LayersBackend layersBackend,
|
||||
layers::ISurfaceAllocator* surfAllocator)
|
||||
static gl::SurfaceCaps
|
||||
BaseCaps(const WebGLContextOptions& options, WebGLContext* webgl)
|
||||
{
|
||||
SurfaceCaps baseCaps;
|
||||
gl::SurfaceCaps baseCaps;
|
||||
|
||||
baseCaps.color = true;
|
||||
baseCaps.alpha = options.alpha;
|
||||
|
@ -691,29 +592,36 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
|
|||
if (!baseCaps.alpha)
|
||||
baseCaps.premultAlpha = true;
|
||||
|
||||
if (gl->IsANGLE() ||
|
||||
(gl->GetContextType() == GLContextType::GLX &&
|
||||
layersBackend == LayersBackend::LAYERS_OPENGL))
|
||||
{
|
||||
// We can't use no-alpha formats on ANGLE yet because of:
|
||||
// https://code.google.com/p/angleproject/issues/detail?id=764
|
||||
// GLX only supports GL_RGBA pixmaps as well. Since we can't blit from
|
||||
// an RGB FB to GLX's RGBA FB, force RGBA when surface sharing.
|
||||
baseCaps.alpha = true;
|
||||
}
|
||||
|
||||
// we should really have this behind a
|
||||
// |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
|
||||
// for now it's just behind a pref for testing/evaluation.
|
||||
baseCaps.bpp16 = Preferences::GetBool("webgl.prefer-16bpp", false);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
baseCaps.surfaceAllocator = surfAllocator;
|
||||
do {
|
||||
auto canvasElement = webgl->GetCanvas();
|
||||
auto ownerDoc = canvasElement->OwnerDoc();
|
||||
nsIWidget* docWidget = nsContentUtils::WidgetForDocument(ownerDoc);
|
||||
if (!docWidget)
|
||||
break;
|
||||
|
||||
layers::LayerManager* layerManager = docWidget->GetLayerManager();
|
||||
if (!layerManager)
|
||||
break;
|
||||
|
||||
// XXX we really want "AsSurfaceAllocator" here for generality
|
||||
layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder();
|
||||
if (!forwarder)
|
||||
break;
|
||||
|
||||
baseCaps.surfaceAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
|
||||
} while (false);
|
||||
#endif
|
||||
|
||||
// Done with baseCaps construction.
|
||||
|
||||
bool forceAllowAA = Preferences::GetBool("webgl.msaa-force", false);
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
if (!forceAllowAA &&
|
||||
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_MSAA))
|
||||
{
|
||||
|
@ -722,62 +630,149 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
|
|||
baseCaps.antialias = false;
|
||||
}
|
||||
|
||||
std::queue<SurfaceCaps> fallbackCaps;
|
||||
return baseCaps;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
static already_AddRefed<gl::GLContext>
|
||||
CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
RefPtr<GLContext> gl;
|
||||
#ifndef XP_MACOSX // Mac doesn't have GLContextProviderEGL.
|
||||
gfx::IntSize dummySize(16, 16);
|
||||
gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps,
|
||||
flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during EGL OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (gl->IsANGLE())
|
||||
return nullptr;
|
||||
#endif // XP_MACOSX
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
RefPtr<GLContext> gl;
|
||||
|
||||
#ifdef XP_WIN
|
||||
gfx::IntSize dummySize(16, 16);
|
||||
gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps, flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during ANGLE OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!gl->IsANGLE())
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<gl::GLContext>
|
||||
CreateGLWithDefault(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
|
||||
if (!(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE) &&
|
||||
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
|
||||
{
|
||||
webgl->GenerateWarning("Refused to create native OpenGL context because of"
|
||||
" blacklisting.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::IntSize dummySize(16, 16);
|
||||
RefPtr<GLContext> gl = gl::GLContextProvider::CreateOffscreen(dummySize, caps, flags);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during native OpenGL init.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (gl->IsANGLE())
|
||||
return nullptr;
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
bool
|
||||
WebGLContext::CreateAndInitGLWith(FnCreateGL_T fnCreateGL,
|
||||
const gl::SurfaceCaps& baseCaps,
|
||||
gl::CreateContextFlags flags)
|
||||
{
|
||||
MOZ_ASSERT(!gl);
|
||||
|
||||
std::queue<gl::SurfaceCaps> fallbackCaps;
|
||||
PopulateCapFallbackQueue(baseCaps, &fallbackCaps);
|
||||
|
||||
bool created = false;
|
||||
gl = nullptr;
|
||||
while (!fallbackCaps.empty()) {
|
||||
SurfaceCaps& caps = fallbackCaps.front();
|
||||
gl::SurfaceCaps& caps = fallbackCaps.front();
|
||||
|
||||
created = CreateOffscreenWithCaps(gl, caps);
|
||||
if (created)
|
||||
gl = fnCreateGL(caps, flags, this);
|
||||
if (gl)
|
||||
break;
|
||||
|
||||
fallbackCaps.pop();
|
||||
}
|
||||
if (!gl)
|
||||
return false;
|
||||
|
||||
return created;
|
||||
if (!InitAndValidateGL()) {
|
||||
gl = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::CreateOffscreenGL(bool forceEnabled)
|
||||
WebGLContext::CreateAndInitGL(bool forceEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL");
|
||||
bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false);
|
||||
|
||||
layers::ISurfaceAllocator* surfAllocator = nullptr;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsIWidget* docWidget = nsContentUtils::WidgetForDocument(mCanvasElement->OwnerDoc());
|
||||
if (docWidget) {
|
||||
layers::LayerManager* layerManager = docWidget->GetLayerManager();
|
||||
if (layerManager) {
|
||||
// XXX we really want "AsSurfaceAllocator" here for generality
|
||||
layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder();
|
||||
if (forwarder)
|
||||
surfAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
|
||||
}
|
||||
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
|
||||
disableANGLE = true;
|
||||
|
||||
gl::CreateContextFlags flags = gl::CreateContextFlags::NONE;
|
||||
if (forceEnabled) flags |= gl::CreateContextFlags::FORCE_ENABLE_HARDWARE;
|
||||
if (!IsWebGL2()) flags |= gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE;
|
||||
|
||||
const gl::SurfaceCaps baseCaps = BaseCaps(mOptions, this);
|
||||
|
||||
MOZ_ASSERT(!gl);
|
||||
|
||||
if (preferEGL) {
|
||||
if (CreateAndInitGLWith(CreateGLWithEGL, baseCaps, flags))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateContextFlags flags = forceEnabled ? CreateContextFlags::FORCE_ENABLE_HARDWARE :
|
||||
CreateContextFlags::NONE;
|
||||
MOZ_ASSERT(!gl);
|
||||
|
||||
gl = CreateHeadlessGL(flags, gfxInfo, this);
|
||||
if (!disableANGLE) {
|
||||
if (CreateAndInitGLWith(CreateGLWithANGLE, baseCaps, flags))
|
||||
return true;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!gl)
|
||||
break;
|
||||
|
||||
if (!CreateOffscreen(gl, mOptions, gfxInfo, this,
|
||||
GetCompositorBackendType(), surfAllocator))
|
||||
break;
|
||||
|
||||
if (!InitAndValidateGL())
|
||||
break;
|
||||
MOZ_ASSERT(!gl);
|
||||
|
||||
if (CreateAndInitGLWith(CreateGLWithDefault, baseCaps, flags))
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
MOZ_ASSERT(!gl);
|
||||
gl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -941,12 +936,15 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
|
|||
bool forceEnabled = Preferences::GetBool("webgl.force-enabled", false);
|
||||
ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
|
||||
|
||||
if (!CreateOffscreenGL(forceEnabled)) {
|
||||
MOZ_ASSERT(!gl);
|
||||
if (!CreateAndInitGL(forceEnabled)) {
|
||||
GenerateWarning("WebGL creation failed.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(gl);
|
||||
|
||||
MOZ_ASSERT_IF(mOptions.alpha, gl->Caps().alpha);
|
||||
|
||||
if (!ResizeBackbuffer(width, height)) {
|
||||
GenerateWarning("Initializing WebGL backbuffer failed.");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -965,14 +963,20 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
|
|||
if (!mOptions.alpha && gl->Caps().alpha)
|
||||
mNeedsFakeNoAlpha = true;
|
||||
|
||||
// ANGLE doesn't quite handle this properly.
|
||||
if (gl->Caps().depth && !gl->Caps().stencil && gl->IsANGLE())
|
||||
if (!mOptions.depth && gl->Caps().depth)
|
||||
mNeedsFakeNoDepth = true;
|
||||
|
||||
if (!mOptions.stencil && gl->Caps().stencil)
|
||||
mNeedsFakeNoStencil = true;
|
||||
}
|
||||
|
||||
// Update mOptions.
|
||||
mOptions.depth = gl->Caps().depth;
|
||||
mOptions.stencil = gl->Caps().stencil;
|
||||
if (!gl->Caps().depth)
|
||||
mOptions.depth = false;
|
||||
|
||||
if (!gl->Caps().stencil)
|
||||
mOptions.stencil = false;
|
||||
|
||||
mOptions.antialias = gl->Caps().antialias;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
@ -998,10 +1002,16 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
|
|||
mShouldPresent = true;
|
||||
|
||||
MOZ_ASSERT(gl->Caps().color);
|
||||
|
||||
MOZ_ASSERT_IF(!mNeedsFakeNoAlpha, gl->Caps().alpha == mOptions.alpha);
|
||||
MOZ_ASSERT_IF(mNeedsFakeNoAlpha, !mOptions.alpha && gl->Caps().alpha);
|
||||
MOZ_ASSERT(gl->Caps().depth == mOptions.depth);
|
||||
MOZ_ASSERT(gl->Caps().stencil == mOptions.stencil);
|
||||
|
||||
MOZ_ASSERT_IF(!mNeedsFakeNoDepth, gl->Caps().depth == mOptions.depth);
|
||||
MOZ_ASSERT_IF(mNeedsFakeNoDepth, !mOptions.depth && gl->Caps().depth);
|
||||
|
||||
MOZ_ASSERT_IF(!mNeedsFakeNoStencil, gl->Caps().stencil == mOptions.stencil);
|
||||
MOZ_ASSERT_IF(mNeedsFakeNoStencil, !mOptions.stencil && gl->Caps().stencil);
|
||||
|
||||
MOZ_ASSERT(gl->Caps().antialias == mOptions.antialias);
|
||||
MOZ_ASSERT(gl->Caps().preserve == mOptions.preserveDrawingBuffer);
|
||||
|
||||
|
@ -1876,6 +1886,7 @@ RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y)
|
|||
WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl)
|
||||
: mWebGL(webgl)
|
||||
, mFakeNoAlpha(ShouldFakeNoAlpha(webgl))
|
||||
, mFakeNoDepth(ShouldFakeNoDepth(webgl))
|
||||
, mFakeNoStencil(ShouldFakeNoStencil(webgl))
|
||||
{
|
||||
if (mFakeNoAlpha) {
|
||||
|
@ -1884,6 +1895,9 @@ WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl)
|
|||
mWebGL.mColorWriteMask[2],
|
||||
false);
|
||||
}
|
||||
if (mFakeNoDepth) {
|
||||
mWebGL.gl->fDisable(LOCAL_GL_DEPTH_TEST);
|
||||
}
|
||||
if (mFakeNoStencil) {
|
||||
mWebGL.gl->fDisable(LOCAL_GL_STENCIL_TEST);
|
||||
}
|
||||
|
@ -1897,6 +1911,9 @@ WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround()
|
|||
mWebGL.mColorWriteMask[2],
|
||||
mWebGL.mColorWriteMask[3]);
|
||||
}
|
||||
if (mFakeNoDepth) {
|
||||
mWebGL.gl->fEnable(LOCAL_GL_DEPTH_TEST);
|
||||
}
|
||||
if (mFakeNoStencil) {
|
||||
mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
|
@ -24,6 +25,7 @@
|
|||
#include "nsLayoutUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "ForceDiscreteGPUHelperCGL.h"
|
||||
|
@ -812,6 +814,7 @@ private:
|
|||
realGLboolean mDitherEnabled;
|
||||
realGLboolean mRasterizerDiscardEnabled;
|
||||
realGLboolean mScissorTestEnabled;
|
||||
realGLboolean mDepthTestEnabled;
|
||||
realGLboolean mStencilTestEnabled;
|
||||
|
||||
bool ValidateCapabilityEnum(GLenum cap, const char* info);
|
||||
|
@ -1153,11 +1156,19 @@ public:
|
|||
protected:
|
||||
bool InitWebGL2();
|
||||
|
||||
bool CreateAndInitGL(bool forceEnabled);
|
||||
bool ResizeBackbuffer(uint32_t width, uint32_t height);
|
||||
|
||||
typedef already_AddRefed<gl::GLContext> FnCreateGL_T(const gl::SurfaceCaps& caps,
|
||||
gl::CreateContextFlags flags,
|
||||
WebGLContext* webgl);
|
||||
|
||||
bool CreateAndInitGLWith(FnCreateGL_T fnCreateGL, const gl::SurfaceCaps& baseCaps,
|
||||
gl::CreateContextFlags flags);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Validation functions (implemented in WebGLContextValidate.cpp)
|
||||
bool CreateOffscreenGL(bool forceEnabled);
|
||||
bool InitAndValidateGL();
|
||||
bool ResizeBackbuffer(uint32_t width, uint32_t height);
|
||||
bool ValidateBlendEquationEnum(GLenum cap, const char* info);
|
||||
bool ValidateBlendFuncDstEnum(GLenum mode, const char* info);
|
||||
bool ValidateBlendFuncSrcEnum(GLenum mode, const char* info);
|
||||
|
@ -1443,11 +1454,13 @@ protected:
|
|||
uint64_t mLastUseIndex;
|
||||
|
||||
bool mNeedsFakeNoAlpha;
|
||||
bool mNeedsFakeNoDepth;
|
||||
bool mNeedsFakeNoStencil;
|
||||
|
||||
struct ScopedMaskWorkaround {
|
||||
WebGLContext& mWebGL;
|
||||
const bool mFakeNoAlpha;
|
||||
const bool mFakeNoDepth;
|
||||
const bool mFakeNoStencil;
|
||||
|
||||
static bool ShouldFakeNoAlpha(WebGLContext& webgl) {
|
||||
|
@ -1458,6 +1471,13 @@ protected:
|
|||
webgl.mColorWriteMask[3] != false;
|
||||
}
|
||||
|
||||
static bool ShouldFakeNoDepth(WebGLContext& webgl) {
|
||||
// We should only be doing this if we're about to draw to the backbuffer.
|
||||
return !webgl.mBoundDrawFramebuffer &&
|
||||
webgl.mNeedsFakeNoDepth &&
|
||||
webgl.mDepthTestEnabled;
|
||||
}
|
||||
|
||||
static bool ShouldFakeNoStencil(WebGLContext& webgl) {
|
||||
// We should only be doing this if we're about to draw to the backbuffer.
|
||||
return !webgl.mBoundDrawFramebuffer &&
|
||||
|
|
|
@ -360,12 +360,18 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
|
||||
case LOCAL_GL_RED_BITS:
|
||||
case LOCAL_GL_GREEN_BITS:
|
||||
case LOCAL_GL_BLUE_BITS:
|
||||
case LOCAL_GL_DEPTH_BITS: {
|
||||
case LOCAL_GL_BLUE_BITS: {
|
||||
GLint i = 0;
|
||||
gl->fGetIntegerv(pname, &i);
|
||||
return JS::Int32Value(i);
|
||||
}
|
||||
case LOCAL_GL_DEPTH_BITS: {
|
||||
GLint i = 0;
|
||||
if (!mNeedsFakeNoDepth) {
|
||||
gl->fGetIntegerv(pname, &i);
|
||||
}
|
||||
return JS::Int32Value(i);
|
||||
}
|
||||
case LOCAL_GL_ALPHA_BITS: {
|
||||
GLint i = 0;
|
||||
if (!mNeedsFakeNoAlpha) {
|
||||
|
@ -622,6 +628,8 @@ realGLboolean*
|
|||
WebGLContext::GetStateTrackingSlot(GLenum cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case LOCAL_GL_DEPTH_TEST:
|
||||
return &mDepthTestEnabled;
|
||||
case LOCAL_GL_DITHER:
|
||||
return &mDitherEnabled;
|
||||
case LOCAL_GL_RASTERIZER_DISCARD:
|
||||
|
|
|
@ -1175,6 +1175,7 @@ WebGLContext::AssertCachedState()
|
|||
}
|
||||
|
||||
// Draw state
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DEPTH_TEST) == mDepthTestEnabled);
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled);
|
||||
MOZ_ASSERT_IF(IsWebGL2(),
|
||||
gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == mRasterizerDiscardEnabled);
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
LOCAL_EGL_NONE, LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
EGLContext eglContext = static_cast<GLContextEGL*>(mGLContext.get())->GetEGLContext();
|
||||
EGLContext eglContext = static_cast<GLContextEGL*>(mGLContext.get())->mContext;
|
||||
EGLImage eglImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext,
|
||||
LOCAL_EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer)tex, attribs);
|
||||
|
|
|
@ -28,7 +28,7 @@ static ANPEGLContext anp_opengl_acquireContext(NPP instance) {
|
|||
return nullptr;
|
||||
|
||||
context->MakeCurrent();
|
||||
return GLContextEGL::Cast(context)->GetEGLContext();
|
||||
return GLContextEGL::Cast(context)->mContext;
|
||||
}
|
||||
|
||||
static ANPTextureInfo anp_opengl_lockTexture(NPP instance) {
|
||||
|
|
|
@ -23,7 +23,7 @@ CreateEGLImage(GLContext* gl, GLuint tex)
|
|||
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
|
||||
|
||||
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
|
||||
EGLContext eglContext = GLContextEGL::Cast(gl)->GetEGLContext();
|
||||
EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
|
||||
EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
|
||||
eglContext,
|
||||
LOCAL_EGL_GL_TEXTURE_2D,
|
||||
|
@ -42,7 +42,7 @@ EGLImageWrapper::Create(GLContext* gl, GLuint tex)
|
|||
|
||||
GLLibraryEGL& library = sEGLLibrary;
|
||||
EGLDisplay display = EGL_DISPLAY();
|
||||
EGLContext eglContext = GLContextEGL::Cast(gl)->GetEGLContext();
|
||||
EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
|
||||
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
|
||||
EGLImage image = library.fCreateImage(display,
|
||||
eglContext,
|
||||
|
|
|
@ -306,7 +306,6 @@ GLContext::GLContext(const SurfaceCaps& caps,
|
|||
mRenderer(GLRenderer::Other),
|
||||
mHasRobustness(false),
|
||||
mTopError(LOCAL_GL_NO_ERROR),
|
||||
mLocalErrorScope(nullptr),
|
||||
mSharedContext(sharedContext),
|
||||
mCaps(caps),
|
||||
mScreen(nullptr),
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#ifndef GLCONTEXT_H_
|
||||
#define GLCONTEXT_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <map>
|
||||
#include <bitset>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <string.h>
|
||||
|
@ -619,7 +620,7 @@ public:
|
|||
class LocalErrorScope;
|
||||
|
||||
private:
|
||||
LocalErrorScope* mLocalErrorScope;
|
||||
std::stack<const LocalErrorScope*> mLocalErrorScopeStack;
|
||||
|
||||
public:
|
||||
class LocalErrorScope {
|
||||
|
@ -632,8 +633,7 @@ public:
|
|||
: mGL(gl)
|
||||
, mHasBeenChecked(false)
|
||||
{
|
||||
MOZ_ASSERT(!mGL.mLocalErrorScope);
|
||||
mGL.mLocalErrorScope = this;
|
||||
mGL.mLocalErrorScopeStack.push(this);
|
||||
|
||||
mGL.FlushErrors();
|
||||
|
||||
|
@ -653,10 +653,10 @@ public:
|
|||
|
||||
MOZ_ASSERT(mGL.fGetError() == LOCAL_GL_NO_ERROR);
|
||||
|
||||
mGL.mTopError = mOldTop;
|
||||
MOZ_ASSERT(mGL.mLocalErrorScopeStack.top() == this);
|
||||
mGL.mLocalErrorScopeStack.pop();
|
||||
|
||||
MOZ_ASSERT(mGL.mLocalErrorScope == this);
|
||||
mGL.mLocalErrorScope = nullptr;
|
||||
mGL.mTopError = mOldTop;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -738,7 +738,7 @@ private:
|
|||
}
|
||||
|
||||
if (err != LOCAL_GL_NO_ERROR &&
|
||||
!mLocalErrorScope)
|
||||
!mLocalErrorScopeStack.size())
|
||||
{
|
||||
printf_stderr("[gl:%p] %s: Generated unexpected %s error."
|
||||
" (0x%04x)\n", this, funcName,
|
||||
|
|
|
@ -92,16 +92,12 @@ public:
|
|||
// for the lifetime of this context.
|
||||
void HoldSurface(gfxASurface *aSurf);
|
||||
|
||||
EGLContext GetEGLContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
EGLSurface GetEGLSurface() {
|
||||
EGLSurface GetEGLSurface() const {
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
EGLDisplay GetEGLDisplay() {
|
||||
return EGL_DISPLAY();
|
||||
EGLDisplay GetEGLDisplay() const {
|
||||
return sEGLLibrary.Display();
|
||||
}
|
||||
|
||||
bool BindTex2DOffscreen(GLContext *aOffscreen);
|
||||
|
@ -112,15 +108,20 @@ public:
|
|||
CreateEGLPixmapOffscreenContext(const gfx::IntSize& size);
|
||||
|
||||
static already_AddRefed<GLContextEGL>
|
||||
CreateEGLPBufferOffscreenContext(const gfx::IntSize& size);
|
||||
CreateEGLPBufferOffscreenContext(const gfx::IntSize& size,
|
||||
const SurfaceCaps& minCaps);
|
||||
|
||||
protected:
|
||||
friend class GLContextProviderEGL;
|
||||
|
||||
EGLConfig mConfig;
|
||||
public:
|
||||
const EGLConfig mConfig;
|
||||
protected:
|
||||
EGLSurface mSurface;
|
||||
public:
|
||||
const EGLContext mContext;
|
||||
protected:
|
||||
EGLSurface mSurfaceOverride;
|
||||
EGLContext mContext;
|
||||
nsRefPtr<gfxASurface> mThebesSurface;
|
||||
bool mBound;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "GLContextTypes.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "SurfaceTypes.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
#include "nsSize.h" // for gfx::IntSize (needed by GLContextProviderImpl.h below)
|
||||
|
||||
|
@ -18,16 +17,6 @@ class nsIWidget;
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
enum class CreateContextFlags : int8_t {
|
||||
NONE = 0,
|
||||
REQUIRE_COMPAT_PROFILE = 1 << 0,
|
||||
// Force the use of hardware backed GL, don't allow software implementations.
|
||||
FORCE_ENABLE_HARDWARE = 1 << 1,
|
||||
/* Don't force discrete GPU to be used (if applicable) */
|
||||
ALLOW_OFFLINE_RENDERER = 1 << 2,
|
||||
};
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CreateContextFlags)
|
||||
|
||||
#define IN_GL_CONTEXT_PROVIDER_H
|
||||
|
||||
// Null is always there
|
||||
|
@ -36,47 +25,45 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CreateContextFlags)
|
|||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderWGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderWGL
|
||||
#define DEFAULT_IMPL WGL
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderWGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderWGL
|
||||
#define DEFAULT_IMPL WGL
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderCGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderCGL
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderCGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderCGL
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderGLX
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderGLX
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID) || defined(XP_WIN)
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderEGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#ifndef GL_CONTEXT_PROVIDER_DEFAULT
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEGL
|
||||
#endif
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEGL
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GL_PROVIDER
|
||||
#define GL_CONTEXT_PROVIDER_NAME MOZ_GL_PROVIDER
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT MOZ_GL_PROVIDER
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11) && !defined(GL_CONTEXT_PROVIDER_DEFAULT)
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderGLX
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderGLX
|
||||
#define GL_CONTEXT_PROVIDER_NAME MOZ_GL_PROVIDER
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT MOZ_GL_PROVIDER
|
||||
#endif
|
||||
|
||||
#ifdef GL_CONTEXT_PROVIDER_DEFAULT
|
||||
typedef GL_CONTEXT_PROVIDER_DEFAULT GLContextProvider;
|
||||
typedef GL_CONTEXT_PROVIDER_DEFAULT GLContextProvider;
|
||||
#else
|
||||
typedef GLContextProviderNull GLContextProvider;
|
||||
typedef GLContextProviderNull GLContextProvider;
|
||||
#endif
|
||||
|
||||
#undef IN_GL_CONTEXT_PROVIDER_H
|
||||
|
|
|
@ -317,16 +317,17 @@ GLContextProviderCGL::CreateHeadless(CreateContextFlags flags)
|
|||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateOffscreen(const IntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const SurfaceCaps& minCaps,
|
||||
CreateContextFlags flags)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(flags);
|
||||
if (!glContext->InitOffscreen(size, caps)) {
|
||||
NS_WARNING("Failed during InitOffscreen.");
|
||||
RefPtr<GLContext> gl = CreateHeadless(flags);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return glContext.forget();
|
||||
if (!gl->InitOffscreen(size, minCaps))
|
||||
return nullptr;
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static nsRefPtr<GLContext> gGlobalContext;
|
||||
|
|
|
@ -3,116 +3,108 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "GLContextEGL.h"
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include <gdk/gdkx.h>
|
||||
// we're using default display for now
|
||||
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow*)aWidget->GetNativeData(NS_NATIVE_WINDOW)))
|
||||
#elif defined(MOZ_WIDGET_QT)
|
||||
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW))
|
||||
#else
|
||||
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "libdisplay/GonkDisplay.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsScreenManagerGonk.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include <gdk/gdkx.h>
|
||||
// we're using default display for now
|
||||
#define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
#elif defined(MOZ_WIDGET_QT)
|
||||
#define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)(aWidget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW))
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
#include "libdisplay/GonkDisplay.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsScreenManagerGonk.h"
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
/* from widget */
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
/* from widget */
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
|
||||
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "cutils/properties.h"
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
# if defined(MOZ_WIDGET_GONK)
|
||||
# include "cutils/properties.h"
|
||||
# include <ui/GraphicBuffer.h>
|
||||
using namespace android;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace android;
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#define GLES2_LIB "libGLESv2.so"
|
||||
#define GLES2_LIB2 "libGLESv2.so.2"
|
||||
#define GLES2_LIB "libGLESv2.so"
|
||||
#define GLES2_LIB2 "libGLESv2.so.2"
|
||||
|
||||
#elif defined(XP_WIN)
|
||||
#include "nsIFile.h"
|
||||
|
||||
#include "nsIFile.h"
|
||||
#define GLES2_LIB "libGLESv2.dll"
|
||||
|
||||
#define GLES2_LIB "libGLESv2.dll"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// a little helper
|
||||
class AutoDestroyHWND {
|
||||
public:
|
||||
AutoDestroyHWND(HWND aWnd = nullptr)
|
||||
: mWnd(aWnd)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoDestroyHWND() {
|
||||
if (mWnd) {
|
||||
::DestroyWindow(mWnd);
|
||||
// a little helper
|
||||
class AutoDestroyHWND {
|
||||
public:
|
||||
AutoDestroyHWND(HWND aWnd = nullptr)
|
||||
: mWnd(aWnd)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
operator HWND() {
|
||||
return mWnd;
|
||||
}
|
||||
|
||||
HWND forget() {
|
||||
HWND w = mWnd;
|
||||
mWnd = nullptr;
|
||||
return w;
|
||||
}
|
||||
|
||||
HWND operator=(HWND aWnd) {
|
||||
if (mWnd && mWnd != aWnd) {
|
||||
::DestroyWindow(mWnd);
|
||||
~AutoDestroyHWND() {
|
||||
if (mWnd) {
|
||||
::DestroyWindow(mWnd);
|
||||
}
|
||||
}
|
||||
mWnd = aWnd;
|
||||
return mWnd;
|
||||
}
|
||||
|
||||
HWND mWnd;
|
||||
};
|
||||
operator HWND() {
|
||||
return mWnd;
|
||||
}
|
||||
|
||||
HWND forget() {
|
||||
HWND w = mWnd;
|
||||
mWnd = nullptr;
|
||||
return w;
|
||||
}
|
||||
|
||||
HWND operator=(HWND aWnd) {
|
||||
if (mWnd && mWnd != aWnd) {
|
||||
::DestroyWindow(mWnd);
|
||||
}
|
||||
mWnd = aWnd;
|
||||
return mWnd;
|
||||
}
|
||||
|
||||
HWND mWnd;
|
||||
};
|
||||
#else
|
||||
|
||||
#error "Platform not recognized"
|
||||
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxFailure.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include "gfxFailure.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "TextureImageEGL.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "GLBlitHelper.h"
|
||||
#include "TextureImageEGL.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
|
@ -190,18 +182,16 @@ DestroySurface(EGLSurface oldSurface) {
|
|||
|
||||
static EGLSurface
|
||||
CreateSurfaceForWindow(nsIWidget* widget, const EGLConfig& config) {
|
||||
EGLSurface newSurface = EGL_NO_SURFACE;
|
||||
EGLSurface newSurface = nullptr;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mozilla::AndroidBridge::Bridge()->RegisterCompositor();
|
||||
newSurface = mozilla::AndroidBridge::Bridge()->CreateEGLSurfaceForCompositor();
|
||||
if (newSurface == EGL_NO_SURFACE) {
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
#else
|
||||
#else
|
||||
MOZ_ASSERT(widget != nullptr);
|
||||
newSurface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, GET_NATIVE_WINDOW(widget), 0);
|
||||
#endif
|
||||
newSurface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config,
|
||||
GET_NATIVE_WINDOW(widget), 0);
|
||||
#endif
|
||||
return newSurface;
|
||||
}
|
||||
|
||||
|
@ -215,8 +205,8 @@ GLContextEGL::GLContextEGL(
|
|||
: GLContext(caps, shareContext, isOffscreen)
|
||||
, mConfig(config)
|
||||
, mSurface(surface)
|
||||
, mSurfaceOverride(EGL_NO_SURFACE)
|
||||
, mContext(context)
|
||||
, mSurfaceOverride(EGL_NO_SURFACE)
|
||||
, mThebesSurface(nullptr)
|
||||
, mBound(false)
|
||||
, mIsPBuffer(false)
|
||||
|
@ -425,7 +415,7 @@ GLContextEGL::RenewSurface() {
|
|||
// If we get here, then by definition we know that we want to get a new surface.
|
||||
ReleaseSurface();
|
||||
mSurface = mozilla::gl::CreateSurfaceForWindow(nullptr, mConfig); // the nullptr here is where we assume Android.
|
||||
if (mSurface == EGL_NO_SURFACE) {
|
||||
if (!mSurface) {
|
||||
return false;
|
||||
}
|
||||
return MakeCurrent(true);
|
||||
|
@ -490,6 +480,10 @@ GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget)
|
|||
}
|
||||
|
||||
EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config);
|
||||
if (!surface) {
|
||||
MOZ_CRASH("Failed to create EGLSurface for window!\n");
|
||||
return nullptr;
|
||||
}
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
@ -780,8 +774,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
|
|||
}
|
||||
|
||||
EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config);
|
||||
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
if (!surface) {
|
||||
MOZ_CRASH("Failed to create EGLSurface!\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -839,60 +832,144 @@ GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface)
|
|||
}
|
||||
#endif // defined(ANDROID)
|
||||
|
||||
already_AddRefed<GLContextEGL>
|
||||
GLContextEGL::CreateEGLPBufferOffscreenContext(const mozilla::gfx::IntSize& size)
|
||||
static void
|
||||
FillContextAttribs(bool alpha, bool depth, bool stencil, bool bpp16,
|
||||
nsTArray<EGLint>* out)
|
||||
{
|
||||
EGLConfig config;
|
||||
EGLSurface surface;
|
||||
out->AppendElement(LOCAL_EGL_SURFACE_TYPE);
|
||||
out->AppendElement(LOCAL_EGL_PBUFFER_BIT);
|
||||
|
||||
const EGLint numConfigs = 1; // We only need one.
|
||||
EGLConfig configs[numConfigs];
|
||||
out->AppendElement(LOCAL_EGL_RENDERABLE_TYPE);
|
||||
out->AppendElement(LOCAL_EGL_OPENGL_ES2_BIT);
|
||||
|
||||
out->AppendElement(LOCAL_EGL_RED_SIZE);
|
||||
if (bpp16) {
|
||||
out->AppendElement(alpha ? 4 : 5);
|
||||
} else {
|
||||
out->AppendElement(8);
|
||||
}
|
||||
|
||||
out->AppendElement(LOCAL_EGL_GREEN_SIZE);
|
||||
if (bpp16) {
|
||||
out->AppendElement(alpha ? 4 : 6);
|
||||
} else {
|
||||
out->AppendElement(8);
|
||||
}
|
||||
|
||||
out->AppendElement(LOCAL_EGL_BLUE_SIZE);
|
||||
if (bpp16) {
|
||||
out->AppendElement(alpha ? 4 : 5);
|
||||
} else {
|
||||
out->AppendElement(8);
|
||||
}
|
||||
|
||||
out->AppendElement(LOCAL_EGL_ALPHA_SIZE);
|
||||
if (alpha) {
|
||||
out->AppendElement(bpp16 ? 4 : 8);
|
||||
} else {
|
||||
out->AppendElement(0);
|
||||
}
|
||||
|
||||
out->AppendElement(LOCAL_EGL_DEPTH_SIZE);
|
||||
out->AppendElement(depth ? 16 : 0);
|
||||
|
||||
out->AppendElement(LOCAL_EGL_STENCIL_SIZE);
|
||||
out->AppendElement(stencil ? 8 : 0);
|
||||
|
||||
// EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
|
||||
out->AppendElement(LOCAL_EGL_NONE);
|
||||
out->AppendElement(0);
|
||||
|
||||
out->AppendElement(0);
|
||||
out->AppendElement(0);
|
||||
}
|
||||
|
||||
static GLint
|
||||
GetAttrib(GLLibraryEGL* egl, EGLConfig config, EGLint attrib)
|
||||
{
|
||||
EGLint bits = 0;
|
||||
egl->fGetConfigAttrib(egl->Display(), config, attrib, &bits);
|
||||
MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static EGLConfig
|
||||
ChooseConfig(GLLibraryEGL* egl, const SurfaceCaps& minCaps,
|
||||
SurfaceCaps* const out_configCaps)
|
||||
{
|
||||
nsTArray<EGLint> configAttribList;
|
||||
FillContextAttribs(minCaps.alpha, minCaps.depth, minCaps.stencil, minCaps.bpp16,
|
||||
&configAttribList);
|
||||
|
||||
const EGLint* configAttribs = configAttribList.Elements();
|
||||
|
||||
// We're guaranteed to get at least minCaps, and the sorting dictated by the spec for
|
||||
// eglChooseConfig reasonably assures that a reasonable 'best' config is on top.
|
||||
const EGLint kMaxConfigs = 1;
|
||||
EGLConfig configs[kMaxConfigs];
|
||||
EGLint foundConfigs = 0;
|
||||
if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(),
|
||||
kEGLConfigAttribsOffscreenPBuffer,
|
||||
configs, numConfigs,
|
||||
&foundConfigs)
|
||||
if (!egl->fChooseConfig(egl->Display(), configAttribs, configs, kMaxConfigs,
|
||||
&foundConfigs)
|
||||
|| foundConfigs == 0)
|
||||
{
|
||||
NS_WARNING("No EGL Config for minimal PBuffer!");
|
||||
return EGL_NO_CONFIG;
|
||||
}
|
||||
|
||||
EGLConfig config = configs[0];
|
||||
|
||||
*out_configCaps = minCaps; // Pick up any preserve, etc.
|
||||
out_configCaps->color = true;
|
||||
out_configCaps->alpha = bool(GetAttrib(egl, config, LOCAL_EGL_ALPHA_SIZE));
|
||||
out_configCaps->depth = bool(GetAttrib(egl, config, LOCAL_EGL_DEPTH_SIZE));
|
||||
out_configCaps->stencil = bool(GetAttrib(egl, config, LOCAL_EGL_STENCIL_SIZE));
|
||||
out_configCaps->bpp16 = (GetAttrib(egl, config, LOCAL_EGL_RED_SIZE) < 8);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<GLContextEGL>
|
||||
GLContextEGL::CreateEGLPBufferOffscreenContext(const mozilla::gfx::IntSize& size,
|
||||
const SurfaceCaps& minCaps)
|
||||
{
|
||||
SurfaceCaps configCaps;
|
||||
EGLConfig config = ChooseConfig(&sEGLLibrary, minCaps, &configCaps);
|
||||
if (config == EGL_NO_CONFIG) {
|
||||
NS_WARNING("Failed to find a compatible config.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We absolutely don't care, so just pick the first one.
|
||||
config = configs[0];
|
||||
if (GLContext::ShouldSpew())
|
||||
sEGLLibrary.DumpEGLConfig(config);
|
||||
|
||||
mozilla::gfx::IntSize pbSize(size);
|
||||
surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
|
||||
LOCAL_EGL_NONE,
|
||||
pbSize);
|
||||
EGLSurface surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
|
||||
LOCAL_EGL_NONE,
|
||||
pbSize);
|
||||
if (!surface) {
|
||||
NS_WARNING("Failed to create PBuffer for context!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
nsRefPtr<GLContextEGL> glContext =
|
||||
GLContextEGL::CreateGLContext(dummyCaps,
|
||||
nullptr, true,
|
||||
config, surface);
|
||||
if (!glContext) {
|
||||
|
||||
RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(configCaps, nullptr, true,
|
||||
config, surface);
|
||||
if (!gl) {
|
||||
NS_WARNING("Failed to create GLContext from PBuffer");
|
||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
||||
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!glContext->Init()) {
|
||||
if (!gl->Init()) {
|
||||
NS_WARNING("Failed to initialize GLContext!");
|
||||
// GLContextEGL::dtor will destroy |surface| for us.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return glContext.forget();
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContextEGL>
|
||||
/*static*/ already_AddRefed<GLContextEGL>
|
||||
GLContextEGL::CreateEGLPixmapOffscreenContext(const mozilla::gfx::IntSize& size)
|
||||
{
|
||||
gfxASurface *thebesSurface = nullptr;
|
||||
|
@ -932,49 +1009,77 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const mozilla::gfx::IntSize& size)
|
|||
return glContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderEGL::CreateHeadless(CreateContextFlags flags)
|
||||
{
|
||||
if (!sEGLLibrary.EnsureInitialized(bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE))) {
|
||||
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
||||
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
|
||||
nsRefPtr<GLContext> glContext;
|
||||
glContext = GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize);
|
||||
if (!glContext)
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
return GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize, dummyCaps);
|
||||
}
|
||||
|
||||
// Under EGL, on Android, pbuffers are supported fine, though
|
||||
// often without the ability to texture from them directly.
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const SurfaceCaps& minCaps,
|
||||
CreateContextFlags flags)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(flags);
|
||||
if (!glContext)
|
||||
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
||||
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware))
|
||||
return nullptr;
|
||||
|
||||
if (!glContext->InitOffscreen(size, caps))
|
||||
bool canOffscreenUseHeadless = true;
|
||||
if (sEGLLibrary.IsANGLE()) {
|
||||
// ANGLE needs to use PBuffers.
|
||||
canOffscreenUseHeadless = false;
|
||||
}
|
||||
|
||||
RefPtr<GLContext> gl;
|
||||
SurfaceCaps offscreenCaps = minCaps;
|
||||
|
||||
if (canOffscreenUseHeadless) {
|
||||
gl = CreateHeadless(flags);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
} else {
|
||||
SurfaceCaps minBackbufferCaps = minCaps;
|
||||
if (minCaps.antialias) {
|
||||
minBackbufferCaps.antialias = false;
|
||||
minBackbufferCaps.depth = false;
|
||||
minBackbufferCaps.stencil = false;
|
||||
}
|
||||
|
||||
gl = GLContextEGL::CreateEGLPBufferOffscreenContext(size, minBackbufferCaps);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
|
||||
offscreenCaps = gl->Caps();
|
||||
if (minCaps.antialias) {
|
||||
offscreenCaps.depth = minCaps.depth;
|
||||
offscreenCaps.stencil = minCaps.stencil;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl->InitOffscreen(size, offscreenCaps))
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
// Don't want a global context on Android as 1) share groups across 2 threads fail on many Tegra drivers (bug 759225)
|
||||
// and 2) some mobile devices have a very strict limit on global number of GL contexts (bug 754257)
|
||||
// and 3) each EGL context eats 750k on B2G (bug 813783)
|
||||
GLContext*
|
||||
/*static*/ GLContext*
|
||||
GLContextProviderEGL::GetGlobalContext()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
/*static*/ void
|
||||
GLContextProviderEGL::Shutdown()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1130,75 +1130,96 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
|
|||
return glContext.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextGLX>
|
||||
CreateOffscreenPixmapContext(const IntSize& size)
|
||||
static bool
|
||||
ChooseConfig(GLXLibrary* glx, Display* display, int screen, const SurfaceCaps& minCaps,
|
||||
ScopedXFree<GLXFBConfig>* const out_scopedConfigArr,
|
||||
GLXFBConfig* const out_config, int* const out_visid)
|
||||
{
|
||||
GLXLibrary& glx = sGLXLibrary;
|
||||
if (!glx.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
ScopedXFree<GLXFBConfig>& scopedConfigArr = *out_scopedConfigArr;
|
||||
|
||||
Display *display = DefaultXDisplay();
|
||||
int xscreen = DefaultScreen(display);
|
||||
if (minCaps.antialias)
|
||||
return false;
|
||||
|
||||
int attribs[] = {
|
||||
LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT,
|
||||
LOCAL_GLX_X_RENDERABLE, True,
|
||||
LOCAL_GLX_RED_SIZE, 8,
|
||||
LOCAL_GLX_GREEN_SIZE, 8,
|
||||
LOCAL_GLX_BLUE_SIZE, 8,
|
||||
LOCAL_GLX_ALPHA_SIZE, minCaps.alpha ? 8 : 0,
|
||||
LOCAL_GLX_DEPTH_SIZE, minCaps.depth ? 16 : 0,
|
||||
LOCAL_GLX_STENCIL_SIZE, minCaps.stencil ? 8 : 0,
|
||||
0
|
||||
};
|
||||
|
||||
int numConfigs = 0;
|
||||
scopedConfigArr = glx->xChooseFBConfig(display, screen, attribs, &numConfigs);
|
||||
if (!scopedConfigArr || !numConfigs)
|
||||
return false;
|
||||
|
||||
ScopedXFree<GLXFBConfig> cfgs;
|
||||
cfgs = glx.xChooseFBConfig(display,
|
||||
xscreen,
|
||||
attribs,
|
||||
&numConfigs);
|
||||
if (!cfgs) {
|
||||
return nullptr;
|
||||
}
|
||||
// Issues with glxChooseFBConfig selection and sorting:
|
||||
// * ALPHA_SIZE is sorted as 'largest total RGBA bits first'. If we don't request
|
||||
// alpha bits, we'll probably get RGBA anyways, since 32 is more than 24.
|
||||
// * DEPTH_SIZE is sorted largest first, including for `0` inputs.
|
||||
// * STENCIL_SIZE is smallest first, but it might return `8` even though we ask for
|
||||
// `0`.
|
||||
|
||||
MOZ_ASSERT(numConfigs > 0,
|
||||
"glXChooseFBConfig() failed to match our requested format and "
|
||||
"violated its spec!");
|
||||
|
||||
int visid = None;
|
||||
int chosenIndex = 0;
|
||||
// For now, we don't care about these. We *will* care when we do XPixmap sharing.
|
||||
|
||||
for (int i = 0; i < numConfigs; ++i) {
|
||||
int dtype;
|
||||
GLXFBConfig curConfig = scopedConfigArr[i];
|
||||
|
||||
if (glx.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_DRAWABLE_TYPE, &dtype) != Success
|
||||
|| !(dtype & LOCAL_GLX_PIXMAP_BIT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (glx.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid) != Success
|
||||
|| visid == 0)
|
||||
int visid;
|
||||
if (glx->xGetFBConfigAttrib(display, curConfig, LOCAL_GLX_VISUAL_ID, &visid)
|
||||
!= Success)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
chosenIndex = i;
|
||||
break;
|
||||
if (!visid)
|
||||
continue;
|
||||
|
||||
*out_config = curConfig;
|
||||
*out_visid = visid;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!visid) {
|
||||
NS_WARNING("glXChooseFBConfig() didn't give us any configs with visuals!");
|
||||
return false;
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextGLX>
|
||||
CreateOffscreenPixmapContext(const IntSize& size, const SurfaceCaps& minCaps)
|
||||
{
|
||||
GLXLibrary* glx = &sGLXLibrary;
|
||||
if (!glx->EnsureInitialized())
|
||||
return nullptr;
|
||||
|
||||
Display* display = DefaultXDisplay();
|
||||
int screen = DefaultScreen(display);
|
||||
|
||||
ScopedXFree<GLXFBConfig> scopedConfigArr;
|
||||
GLXFBConfig config;
|
||||
int visid;
|
||||
if (!ChooseConfig(glx, display, screen, minCaps, &scopedConfigArr, &config, &visid)) {
|
||||
NS_WARNING("Failed to find a compatible config.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Visual *visual;
|
||||
Visual* visual;
|
||||
int depth;
|
||||
FindVisualAndDepth(display, visid, &visual, &depth);
|
||||
ScopedXErrorHandler xErrorHandler;
|
||||
GLXPixmap glxpixmap = 0;
|
||||
bool error = false;
|
||||
|
||||
IntSize dummySize(16, 16);
|
||||
nsRefPtr<gfxXlibSurface> xsurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
|
||||
visual,
|
||||
dummySize);
|
||||
if (xsurface->CairoStatus() != 0) {
|
||||
ScopedXErrorHandler xErrorHandler;
|
||||
bool error = false;
|
||||
// Must be declared before goto:
|
||||
Drawable drawable;
|
||||
GLXPixmap pixmap;
|
||||
|
||||
gfx::IntSize dummySize(16, 16);
|
||||
RefPtr<gfxXlibSurface> surface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
|
||||
visual,
|
||||
dummySize);
|
||||
if (surface->CairoStatus() != 0) {
|
||||
error = true;
|
||||
goto DONE_CREATING_PIXMAP;
|
||||
}
|
||||
|
@ -1206,73 +1227,60 @@ CreateOffscreenPixmapContext(const IntSize& size)
|
|||
// Handle slightly different signature between glXCreatePixmap and
|
||||
// its pre-GLX-1.3 extension equivalent (though given the ABI, we
|
||||
// might not need to).
|
||||
if (glx.GLXVersionCheck(1, 3)) {
|
||||
glxpixmap = glx.xCreatePixmap(display,
|
||||
cfgs[chosenIndex],
|
||||
xsurface->XDrawable(),
|
||||
nullptr);
|
||||
drawable = surface->XDrawable();
|
||||
if (glx->GLXVersionCheck(1, 3)) {
|
||||
pixmap = glx->xCreatePixmap(display, config, drawable, nullptr);
|
||||
} else {
|
||||
glxpixmap = glx.xCreateGLXPixmapWithConfig(display,
|
||||
cfgs[chosenIndex],
|
||||
xsurface->
|
||||
XDrawable());
|
||||
pixmap = glx->xCreateGLXPixmapWithConfig(display, config, drawable);
|
||||
}
|
||||
if (glxpixmap == 0) {
|
||||
|
||||
if (pixmap == 0) {
|
||||
error = true;
|
||||
}
|
||||
|
||||
DONE_CREATING_PIXMAP:
|
||||
|
||||
nsRefPtr<GLContextGLX> glContext;
|
||||
bool serverError = xErrorHandler.SyncAndGetError(display);
|
||||
if (error || serverError)
|
||||
return nullptr;
|
||||
|
||||
if (!error && // earlier recorded error
|
||||
!serverError)
|
||||
{
|
||||
// We might have an alpha channel, but it doesn't matter.
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
GLContextGLX* shareContext = GetGlobalContextGLX();
|
||||
|
||||
glContext = GLContextGLX::CreateGLContext(dummyCaps,
|
||||
shareContext,
|
||||
true,
|
||||
display,
|
||||
glxpixmap,
|
||||
cfgs[chosenIndex],
|
||||
true,
|
||||
xsurface);
|
||||
}
|
||||
|
||||
return glContext.forget();
|
||||
GLContextGLX* shareContext = GetGlobalContextGLX();
|
||||
return GLContextGLX::CreateGLContext(minCaps, shareContext, true, display, pixmap,
|
||||
config, true, surface);
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderGLX::CreateHeadless(CreateContextFlags)
|
||||
{
|
||||
IntSize dummySize = IntSize(16, 16);
|
||||
nsRefPtr<GLContext> glContext = CreateOffscreenPixmapContext(dummySize);
|
||||
if (!glContext)
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
return CreateOffscreenPixmapContext(dummySize, dummyCaps);
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderGLX::CreateOffscreen(const IntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const SurfaceCaps& minCaps,
|
||||
CreateContextFlags flags)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(flags);
|
||||
if (!glContext)
|
||||
SurfaceCaps minBackbufferCaps = minCaps;
|
||||
if (minCaps.antialias) {
|
||||
minBackbufferCaps.antialias = false;
|
||||
minBackbufferCaps.depth = false;
|
||||
minBackbufferCaps.stencil = false;
|
||||
}
|
||||
|
||||
RefPtr<GLContext> gl;
|
||||
gl = CreateOffscreenPixmapContext(size, minBackbufferCaps);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
|
||||
if (!glContext->InitOffscreen(size, caps))
|
||||
if (!gl->InitOffscreen(size, minCaps))
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
GLContext*
|
||||
/*static*/ GLContext*
|
||||
GLContextProviderGLX::GetGlobalContext()
|
||||
{
|
||||
static bool checkedContextSharing = false;
|
||||
|
@ -1293,17 +1301,19 @@ GLContextProviderGLX::GetGlobalContext()
|
|||
triedToCreateContext = true;
|
||||
|
||||
IntSize dummySize = IntSize(16, 16);
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
// StaticPtr doesn't support assignments from already_AddRefed,
|
||||
// so use a temporary nsRefPtr to make the reference counting
|
||||
// fall out correctly.
|
||||
nsRefPtr<GLContext> holder = CreateOffscreenPixmapContext(dummySize);
|
||||
RefPtr<GLContext> holder;
|
||||
holder = CreateOffscreenPixmapContext(dummySize, dummyCaps);
|
||||
gGlobalContext = holder;
|
||||
}
|
||||
|
||||
return gGlobalContext;
|
||||
}
|
||||
|
||||
void
|
||||
/*static*/ void
|
||||
GLContextProviderGLX::Shutdown()
|
||||
{
|
||||
gGlobalContext = nullptr;
|
||||
|
|
|
@ -54,16 +54,18 @@ public:
|
|||
* resource sharing can be avoided on the target platform, it will
|
||||
* be, in order to isolate the offscreen context.
|
||||
*
|
||||
* @param size The initial size of this offscreen context.
|
||||
* @param caps The SurfaceCaps for this offscreen context.
|
||||
* @param flags The set of CreateContextFlags to be used for this
|
||||
* offscreen context.
|
||||
* @param size The initial size of this offscreen context.
|
||||
* @param minCaps The required SurfaceCaps for this offscreen context. The resulting
|
||||
* context *may* have more/better caps than requested, but it cannot
|
||||
* have fewer/worse caps than requested.
|
||||
* @param flags The set of CreateContextFlags to be used for this
|
||||
* offscreen context.
|
||||
*
|
||||
* @return Context to use for offscreen rendering
|
||||
*/
|
||||
static already_AddRefed<GLContext>
|
||||
CreateOffscreen(const mozilla::gfx::IntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const SurfaceCaps& minCaps,
|
||||
CreateContextFlags flags);
|
||||
|
||||
// Just create a context. We'll add offscreen stuff ourselves.
|
||||
|
|
|
@ -606,7 +606,7 @@ CreateWindowOffscreenContext()
|
|||
return glContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderWGL::CreateHeadless(CreateContextFlags)
|
||||
{
|
||||
if (!sWGLLib.EnsureInitialized()) {
|
||||
|
@ -639,24 +639,24 @@ GLContextProviderWGL::CreateHeadless(CreateContextFlags)
|
|||
return retGL.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
/*static*/ already_AddRefed<GLContext>
|
||||
GLContextProviderWGL::CreateOffscreen(const IntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const SurfaceCaps& minCaps,
|
||||
CreateContextFlags flags)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(flags);
|
||||
if (!glContext)
|
||||
RefPtr<GLContext> gl = CreateHeadless(flags);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
|
||||
if (!glContext->InitOffscreen(size, caps))
|
||||
if (!gl->InitOffscreen(size, minCaps))
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
static nsRefPtr<GLContextWGL> gGlobalContext;
|
||||
|
||||
GLContext *
|
||||
/*static*/ GLContext*
|
||||
GLContextProviderWGL::GetGlobalContext()
|
||||
{
|
||||
if (!sWGLLib.EnsureInitialized()) {
|
||||
|
@ -684,7 +684,7 @@ GLContextProviderWGL::GetGlobalContext()
|
|||
return static_cast<GLContext*>(gGlobalContext);
|
||||
}
|
||||
|
||||
void
|
||||
/*static*/ void
|
||||
GLContextProviderWGL::Shutdown()
|
||||
{
|
||||
gGlobalContext = nullptr;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define GLCONTEXT_TYPES_H_
|
||||
|
||||
#include "GLTypes.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -43,6 +44,16 @@ struct GLFormats
|
|||
GLsizei samples;
|
||||
};
|
||||
|
||||
enum class CreateContextFlags : int8_t {
|
||||
NONE = 0,
|
||||
REQUIRE_COMPAT_PROFILE = 1 << 0,
|
||||
// Force the use of hardware backed GL, don't allow software implementations.
|
||||
FORCE_ENABLE_HARDWARE = 1 << 1,
|
||||
/* Don't force discrete GPU to be used (if applicable) */
|
||||
ALLOW_OFFLINE_RENDERER = 1 << 2,
|
||||
};
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CreateContextFlags)
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
|
|
@ -17,40 +17,32 @@
|
|||
#include <bitset>
|
||||
#include <vector>
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#ifdef XP_WIN
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#else
|
||||
typedef void *EGLNativeDisplayType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void* EGLNativeDisplayType;
|
||||
typedef void* EGLNativePixmapType;
|
||||
typedef void* EGLNativeWindowType;
|
||||
|
||||
#ifdef ANDROID
|
||||
// We only need to explicitly dlopen egltrace
|
||||
// on android as we can use LD_PRELOAD or other tricks
|
||||
// on other platforms. We look for it in /data/local
|
||||
// as that's writeable by all users
|
||||
//
|
||||
// This should really go in GLLibraryEGL.cpp but we currently reference
|
||||
// APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring
|
||||
// will come in subsequent patches on Bug 732865
|
||||
#define APITRACE_LIB "/data/local/tmp/egltrace.so"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
#endif // ANDROID
|
||||
#ifdef ANDROID
|
||||
// We only need to explicitly dlopen egltrace
|
||||
// on android as we can use LD_PRELOAD or other tricks
|
||||
// on other platforms. We look for it in /data/local
|
||||
// as that's writeable by all users
|
||||
//
|
||||
// This should really go in GLLibraryEGL.cpp but we currently reference
|
||||
// APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring
|
||||
// will come in subsequent patches on Bug 732865
|
||||
#define APITRACE_LIB "/data/local/tmp/egltrace.so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
|
|
|
@ -486,9 +486,16 @@ GLScreenBuffer::Swap(const gfx::IntSize& size)
|
|||
//uint32_t srcPixel = ReadPixel(src);
|
||||
//uint32_t destPixel = ReadPixel(dest);
|
||||
//printf_stderr("Before: src: 0x%08x, dest: 0x%08x\n", srcPixel, destPixel);
|
||||
#ifdef DEBUG
|
||||
GLContext::LocalErrorScope errorScope(*mGL);
|
||||
#endif
|
||||
|
||||
SharedSurface::ProdCopy(src, dest, mFactory.get());
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!errorScope.GetError());
|
||||
#endif
|
||||
|
||||
//srcPixel = ReadPixel(src);
|
||||
//destPixel = ReadPixel(dest);
|
||||
//printf_stderr("After: src: 0x%08x, dest: 0x%08x\n", srcPixel, destPixel);
|
||||
|
|
|
@ -41,17 +41,14 @@ CreatePBufferSurface(GLLibraryEGL* egl,
|
|||
}
|
||||
|
||||
/*static*/ UniquePtr<SharedSurface_ANGLEShareHandle>
|
||||
SharedSurface_ANGLEShareHandle::Create(GLContext* gl,
|
||||
EGLContext context, EGLConfig config,
|
||||
SharedSurface_ANGLEShareHandle::Create(GLContext* gl, EGLConfig config,
|
||||
const gfx::IntSize& size, bool hasAlpha)
|
||||
{
|
||||
GLLibraryEGL* egl = &sEGLLibrary;
|
||||
MOZ_ASSERT(egl);
|
||||
MOZ_ASSERT(egl->IsExtensionSupported(
|
||||
GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
|
||||
|
||||
if (!context || !config)
|
||||
return nullptr;
|
||||
MOZ_ASSERT(config);
|
||||
|
||||
EGLDisplay display = egl->Display();
|
||||
EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size);
|
||||
|
@ -82,8 +79,8 @@ SharedSurface_ANGLEShareHandle::Create(GLContext* gl,
|
|||
}
|
||||
|
||||
typedef SharedSurface_ANGLEShareHandle ptrT;
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, context,
|
||||
pbuffer, shareHandle, keyedMutex, fence) );
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, pbuffer, shareHandle,
|
||||
keyedMutex, fence) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
|
@ -97,7 +94,6 @@ SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
|
|||
GLLibraryEGL* egl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
EGLContext context,
|
||||
EGLSurface pbuffer,
|
||||
HANDLE shareHandle,
|
||||
const RefPtr<IDXGIKeyedMutex>& keyedMutex,
|
||||
|
@ -109,7 +105,6 @@ SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
|
|||
hasAlpha,
|
||||
true)
|
||||
, mEGL(egl)
|
||||
, mContext(context)
|
||||
, mPBuffer(pbuffer)
|
||||
, mShareHandle(shareHandle)
|
||||
, mKeyedMutex(keyedMutex)
|
||||
|
@ -281,137 +276,6 @@ SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* c
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Factory
|
||||
|
||||
static void
|
||||
FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
|
||||
int redBits, int greenBits,
|
||||
int blueBits, int alphaBits,
|
||||
int depthBits, int stencilBits)
|
||||
{
|
||||
aAttrs.Clear();
|
||||
|
||||
#if defined(A1) || defined(A2)
|
||||
#error The temp-macro names we want are already defined.
|
||||
#endif
|
||||
|
||||
#define A1(_x) do { aAttrs.AppendElement(_x); } while (0)
|
||||
#define A2(_x,_y) do { A1(_x); A1(_y); } while (0)
|
||||
|
||||
A2(LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT);
|
||||
A2(LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT);
|
||||
|
||||
A2(LOCAL_EGL_RED_SIZE, redBits);
|
||||
A2(LOCAL_EGL_GREEN_SIZE, greenBits);
|
||||
A2(LOCAL_EGL_BLUE_SIZE, blueBits);
|
||||
A2(LOCAL_EGL_ALPHA_SIZE, alphaBits);
|
||||
|
||||
A2(LOCAL_EGL_DEPTH_SIZE, depthBits);
|
||||
A2(LOCAL_EGL_STENCIL_SIZE, stencilBits);
|
||||
|
||||
A1(LOCAL_EGL_NONE);
|
||||
#undef A1
|
||||
#undef A2
|
||||
}
|
||||
|
||||
static void
|
||||
FillPBufferAttribs_BySizes(nsTArray<EGLint>& attribs,
|
||||
bool bpp16, bool hasAlpha,
|
||||
int depthBits, int stencilBits)
|
||||
{
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
int alpha = 0;
|
||||
|
||||
if (bpp16) {
|
||||
if (hasAlpha) {
|
||||
red = green = blue = alpha = 4;
|
||||
} else {
|
||||
red = 5;
|
||||
green = 6;
|
||||
blue = 5;
|
||||
}
|
||||
} else {
|
||||
red = green = blue = 8;
|
||||
if (hasAlpha)
|
||||
alpha = 8;
|
||||
}
|
||||
|
||||
FillPBufferAttribs_ByBits(attribs, red, green, blue, alpha, depthBits,
|
||||
stencilBits);
|
||||
}
|
||||
|
||||
static bool
|
||||
DoesAttribBitsMatchCapBool(GLLibraryEGL* egl, EGLConfig config, EGLint attrib,
|
||||
bool capBool)
|
||||
{
|
||||
EGLint bits = 0;
|
||||
egl->fGetConfigAttrib(egl->Display(), config, attrib, &bits);
|
||||
MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
|
||||
|
||||
bool hasBits = !!bits;
|
||||
|
||||
return hasBits == capBool;
|
||||
}
|
||||
|
||||
static EGLConfig
|
||||
ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps)
|
||||
{
|
||||
MOZ_ASSERT(egl);
|
||||
MOZ_ASSERT(caps.color);
|
||||
|
||||
// We might want 24-bit depth, but we're only (fairly) sure to get 16-bit.
|
||||
int depthBits = caps.depth ? 16 : 0;
|
||||
int stencilBits = caps.stencil ? 8 : 0;
|
||||
|
||||
// Ok, now we have everything.
|
||||
nsTArray<EGLint> attribs(32);
|
||||
FillPBufferAttribs_BySizes(attribs, caps.bpp16, caps.alpha, depthBits,
|
||||
stencilBits);
|
||||
|
||||
// Time to try to get this config:
|
||||
EGLConfig configs[64];
|
||||
int numConfigs = sizeof(configs)/sizeof(EGLConfig);
|
||||
int foundConfigs = 0;
|
||||
|
||||
if (!egl->fChooseConfig(egl->Display(), attribs.Elements(), configs,
|
||||
numConfigs, &foundConfigs) ||
|
||||
!foundConfigs)
|
||||
{
|
||||
NS_WARNING("No configs found for the requested formats.");
|
||||
return EGL_NO_CONFIG;
|
||||
}
|
||||
|
||||
// The requests passed to ChooseConfig are treated as minimums. If you ask
|
||||
// for 0 bits of alpha, we might still get 8 bits.
|
||||
EGLConfig config = EGL_NO_CONFIG;
|
||||
for (int i = 0; i < foundConfigs; i++) {
|
||||
EGLConfig cur = configs[i];
|
||||
if (!DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_ALPHA_SIZE,
|
||||
caps.alpha) ||
|
||||
!DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_DEPTH_SIZE,
|
||||
caps.depth) ||
|
||||
!DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_STENCIL_SIZE,
|
||||
caps.stencil))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
config = cur;
|
||||
break;
|
||||
}
|
||||
|
||||
if (config == EGL_NO_CONFIG) {
|
||||
NS_WARNING("No acceptable EGLConfig found.");
|
||||
return EGL_NO_CONFIG;
|
||||
}
|
||||
|
||||
if (gl->DebugMode()) {
|
||||
egl->DumpEGLConfig(config);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
|
||||
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
|
@ -425,13 +289,10 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
|
|||
if (!egl->IsExtensionSupported(ext))
|
||||
return nullptr;
|
||||
|
||||
bool success;
|
||||
EGLConfig config = GLContextEGL::Cast(gl)->mConfig;
|
||||
|
||||
typedef SurfaceFactory_ANGLEShareHandle ptrT;
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, &success) );
|
||||
|
||||
if (!success)
|
||||
return nullptr;
|
||||
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, config) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
|
@ -440,22 +301,12 @@ SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
|
|||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags,
|
||||
GLLibraryEGL* egl,
|
||||
bool* const out_success)
|
||||
EGLConfig config)
|
||||
: SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
|
||||
, mProdGL(gl)
|
||||
, mEGL(egl)
|
||||
{
|
||||
MOZ_ASSERT(out_success);
|
||||
*out_success = false;
|
||||
|
||||
mContext = GLContextEGL::Cast(mProdGL)->GetEGLContext();
|
||||
mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
|
||||
if (mConfig == EGL_NO_CONFIG)
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(mConfig && mContext);
|
||||
*out_success = true;
|
||||
}
|
||||
, mConfig(config)
|
||||
{ }
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -23,7 +23,6 @@ class SharedSurface_ANGLEShareHandle
|
|||
{
|
||||
public:
|
||||
static UniquePtr<SharedSurface_ANGLEShareHandle> Create(GLContext* gl,
|
||||
EGLContext context,
|
||||
EGLConfig config,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
|
@ -36,7 +35,6 @@ public:
|
|||
|
||||
protected:
|
||||
GLLibraryEGL* const mEGL;
|
||||
const EGLContext mContext;
|
||||
const EGLSurface mPBuffer;
|
||||
public:
|
||||
const HANDLE mShareHandle;
|
||||
|
@ -51,7 +49,6 @@ protected:
|
|||
GLLibraryEGL* egl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
EGLContext context,
|
||||
EGLSurface pbuffer,
|
||||
HANDLE shareHandle,
|
||||
const RefPtr<IDXGIKeyedMutex>& keyedMutex,
|
||||
|
@ -94,8 +91,7 @@ class SurfaceFactory_ANGLEShareHandle
|
|||
protected:
|
||||
GLContext* const mProdGL;
|
||||
GLLibraryEGL* const mEGL;
|
||||
EGLContext mContext;
|
||||
EGLConfig mConfig;
|
||||
const EGLConfig mConfig;
|
||||
|
||||
public:
|
||||
static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
|
||||
|
@ -107,13 +103,11 @@ protected:
|
|||
SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags, GLLibraryEGL* egl,
|
||||
bool* const out_success);
|
||||
EGLConfig config);
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
return SharedSurface_ANGLEShareHandle::Create(mProdGL,
|
||||
mContext, mConfig,
|
||||
size, hasAlpha);
|
||||
return SharedSurface_ANGLEShareHandle::Create(mProdGL, mConfig, size, hasAlpha);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
|||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
|
||||
EGLContext context = GLContextEGL::Cast(prodGL)->mContext;
|
||||
|
||||
typedef SurfaceFactory_EGLImage ptrT;
|
||||
UniquePtr<ptrT> ret;
|
||||
|
|
|
@ -71,7 +71,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'WGLLibrary.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'GLContextProviderEGL.cpp',
|
||||
'GLContextProviderWGL.cpp',
|
||||
'SharedSurfaceANGLE.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_ENABLE_SKIA_GPU']:
|
||||
|
@ -113,10 +113,6 @@ elif gl_provider == 'GLX':
|
|||
EXPORTS += [
|
||||
'SharedSurfaceGLX.h'
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'GLContextProvider%s.cpp' % gl_provider,
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AndroidNativeWindow.cpp',
|
||||
|
@ -127,6 +123,7 @@ UNIFIED_SOURCES += [
|
|||
'GLBlitHelper.cpp',
|
||||
'GLContext.cpp',
|
||||
'GLContextFeatures.cpp',
|
||||
'GLContextProviderEGL.cpp',
|
||||
'GLContextTypes.cpp',
|
||||
'GLDebugUtils.cpp',
|
||||
'GLLibraryEGL.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче