mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1124394 - Support Core profiles for GLContext. - r=kamidphish
This commit is contained in:
parent
d4d465b6d0
commit
ea33309bb2
@ -505,7 +505,7 @@ IsFeatureInBlacklist(const nsCOMPtr<nsIGfxInfo>& gfxInfo, int32_t feature)
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
bool requireCompatProfile, WebGLContext* webgl)
|
||||
{
|
||||
if (!forceEnabled &&
|
||||
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
|
||||
@ -515,7 +515,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless();
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during native OpenGL init.");
|
||||
return nullptr;
|
||||
@ -530,7 +530,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
// Eventually, we want to be able to pick ANGLE-EGL or native EGL.
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
bool requireCompatProfile, WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
@ -543,7 +543,7 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless();
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during ANGLE OpenGL init.");
|
||||
return nullptr;
|
||||
@ -555,13 +555,13 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
#ifdef ANDROID
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless();
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during EGL OpenGL init.");
|
||||
return nullptr;
|
||||
@ -583,16 +583,22 @@ CreateHeadlessGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
|
||||
disableANGLE = true;
|
||||
|
||||
bool requireCompatProfile = webgl->IsWebGL2() ? false : true;
|
||||
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
if (preferEGL)
|
||||
gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl);
|
||||
gl = CreateHeadlessEGL(forceEnabled, requireCompatProfile, webgl);
|
||||
|
||||
if (!gl && !disableANGLE)
|
||||
gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, webgl);
|
||||
if (!gl && !disableANGLE) {
|
||||
gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, requireCompatProfile,
|
||||
webgl);
|
||||
}
|
||||
|
||||
if (!gl)
|
||||
gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, webgl);
|
||||
if (!gl) {
|
||||
gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo,
|
||||
requireCompatProfile, webgl);
|
||||
}
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
@ -1209,9 +1209,10 @@ protected:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// WebGL 2 specifics (implemented in WebGL2Context.cpp)
|
||||
|
||||
public:
|
||||
virtual bool IsWebGL2() const = 0;
|
||||
|
||||
protected:
|
||||
bool InitWebGL2();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -2106,7 +2106,6 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
||||
|
||||
// if we're reading alpha, we may need to do fixup. Note that we don't allow
|
||||
// GL_ALPHA to readpixels currently, but we had the code written for it already.
|
||||
|
||||
const bool formatHasAlpha = format == LOCAL_GL_ALPHA ||
|
||||
format == LOCAL_GL_RGBA;
|
||||
if (!formatHasAlpha)
|
||||
|
@ -1117,11 +1117,12 @@ WebGLContext::AssertCachedState()
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue);
|
||||
|
||||
GLint stencilBits = 0;
|
||||
gl->fGetIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
|
||||
if (GetStencilBits(&stencilBits)) {
|
||||
const GLuint stencilRefMask = (1 << stencilBits) - 1;
|
||||
|
||||
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
|
||||
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
|
||||
}
|
||||
|
||||
// GLES 3.0.4, $4.1.4, p177:
|
||||
// [...] the front and back stencil mask are both set to the value `2^s - 1`, where
|
||||
|
@ -1779,8 +1779,8 @@ WebGLContext::InitAndValidateGL()
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
// on desktop OpenGL, we always keep vertex attrib 0 array enabled
|
||||
if (!gl->IsGLES())
|
||||
// For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled.
|
||||
if (gl->IsCompatibilityProfile())
|
||||
gl->fEnableVertexAttribArray(0);
|
||||
|
||||
if (MinCapabilityMode())
|
||||
@ -1889,7 +1889,7 @@ WebGLContext::InitAndValidateGL()
|
||||
// Always 1 for GLES2
|
||||
mMaxFramebufferColorAttachments = 1;
|
||||
|
||||
if (!gl->IsGLES()) {
|
||||
if (gl->IsCompatibilityProfile()) {
|
||||
// gl_PointSize is always available in ES2 GLSL, but has to be
|
||||
// specifically enabled on desktop GLSL.
|
||||
gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
@ -182,7 +182,7 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
mGLContext = GLContextProvider::CreateHeadless();
|
||||
mGLContext = GLContextProvider::CreateHeadless(false);
|
||||
return mGLContext;
|
||||
}
|
||||
|
||||
|
@ -91,9 +91,8 @@ static nsRefPtr<GLContext> sPluginContext = nullptr;
|
||||
static bool EnsureGLContext()
|
||||
{
|
||||
if (!sPluginContext) {
|
||||
gfxIntSize dummySize(16, 16);
|
||||
sPluginContext = GLContextProvider::CreateOffscreen(dummySize,
|
||||
SurfaceCaps::Any());
|
||||
bool requireCompatProfile = true;
|
||||
sPluginContext = GLContextProvider::CreateHeadless(requireCompatProfile);
|
||||
}
|
||||
|
||||
return sPluginContext != nullptr;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLBlitHelper.h"
|
||||
@ -156,8 +157,7 @@ static const char *sExtensionNames[] = {
|
||||
"GL_OES_texture_half_float",
|
||||
"GL_OES_texture_half_float_linear",
|
||||
"GL_OES_texture_npot",
|
||||
"GL_OES_vertex_array_object",
|
||||
nullptr
|
||||
"GL_OES_vertex_array_object"
|
||||
};
|
||||
|
||||
static bool
|
||||
@ -501,6 +501,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
|
||||
MakeCurrent();
|
||||
if (mInitialized) {
|
||||
MOZ_ASSERT(mProfile != ContextProfile::Unknown);
|
||||
|
||||
uint32_t version = 0;
|
||||
ParseGLVersion(this, &version);
|
||||
|
||||
@ -656,6 +658,15 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
|
||||
SymLoadStruct moreSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } },
|
||||
END_SYMBOLS
|
||||
};
|
||||
|
||||
MOZ_ALWAYS_TRUE(LoadSymbols(moreSymbols, trygl, prefix));
|
||||
}
|
||||
|
||||
InitExtensions();
|
||||
InitFeatures();
|
||||
|
||||
@ -670,12 +681,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
MarkUnsupported(GLFeature::standard_derivatives);
|
||||
}
|
||||
|
||||
if (Vendor() == GLVendor::Imagination &&
|
||||
Renderer() == GLRenderer::SGX540) {
|
||||
// Bug 980048
|
||||
MarkExtensionUnsupported(OES_EGL_sync);
|
||||
}
|
||||
|
||||
if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) {
|
||||
// Bug 978966: on Microsoft's "Basic Render Driver" (software renderer)
|
||||
// multisampling hardcodes blending with the default blendfunc, which breaks WebGL.
|
||||
@ -1468,10 +1473,13 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
// We're ready for final setup.
|
||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (mCaps.any)
|
||||
DetermineCaps();
|
||||
// TODO: Remove SurfaceCaps::any.
|
||||
if (mCaps.any) {
|
||||
mCaps.any = false;
|
||||
mCaps.color = true;
|
||||
mCaps.alpha = false;
|
||||
}
|
||||
|
||||
UpdatePixelFormat();
|
||||
UpdateGLFormats(mCaps);
|
||||
|
||||
mTexGarbageBin = new TextureGarbageBin(this);
|
||||
@ -1593,31 +1601,63 @@ GLContext::DebugCallback(GLenum source,
|
||||
void
|
||||
GLContext::InitExtensions()
|
||||
{
|
||||
MakeCurrent();
|
||||
const char* extensions = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
|
||||
if (!extensions)
|
||||
return;
|
||||
MOZ_ASSERT(IsCurrent());
|
||||
|
||||
InitializeExtensionsBitSet(mAvailableExtensions, extensions,
|
||||
sExtensionNames);
|
||||
std::vector<nsCString> driverExtensionList;
|
||||
|
||||
if (WorkAroundDriverBugs() &&
|
||||
Vendor() == GLVendor::Qualcomm) {
|
||||
if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
|
||||
GLuint count = 0;
|
||||
GetUIntegerv(LOCAL_GL_NUM_EXTENSIONS, &count);
|
||||
for (GLuint i = 0; i < count; i++) {
|
||||
// This is UTF-8.
|
||||
const char* rawExt = (const char*)fGetStringi(LOCAL_GL_EXTENSIONS, i);
|
||||
|
||||
// We CANNOT use nsDependentCString here, because the spec doesn't guarantee
|
||||
// that the pointers returned are different, only that their contents are.
|
||||
// On Flame, each of these index string queries returns the same address.
|
||||
driverExtensionList.push_back(nsCString(rawExt));
|
||||
}
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(!fGetError());
|
||||
const char* rawExts = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
|
||||
MOZ_ALWAYS_TRUE(!fGetError());
|
||||
|
||||
if (rawExts) {
|
||||
nsDependentCString exts(rawExts);
|
||||
SplitByChar(exts, ' ', &driverExtensionList);
|
||||
}
|
||||
}
|
||||
|
||||
const bool shouldDumpExts = ShouldDumpExts();
|
||||
if (shouldDumpExts) {
|
||||
printf_stderr("%i GL driver extensions: (*: recognized)\n",
|
||||
(uint32_t)driverExtensionList.size());
|
||||
}
|
||||
|
||||
MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sExtensionNames,
|
||||
&mAvailableExtensions);
|
||||
|
||||
if (WorkAroundDriverBugs()) {
|
||||
if (Vendor() == GLVendor::Qualcomm) {
|
||||
// Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
|
||||
MarkExtensionSupported(OES_EGL_sync);
|
||||
}
|
||||
|
||||
if (WorkAroundDriverBugs() &&
|
||||
Renderer() == GLRenderer::AndroidEmulator) {
|
||||
if (Vendor() == GLVendor::Imagination &&
|
||||
Renderer() == GLRenderer::SGX540)
|
||||
{
|
||||
// Bug 980048
|
||||
MarkExtensionUnsupported(OES_EGL_sync);
|
||||
}
|
||||
|
||||
if (Renderer() == GLRenderer::AndroidEmulator) {
|
||||
// the Android emulator, which we use to run B2G reftests on,
|
||||
// doesn't expose the OES_rgb8_rgba8 extension, but it seems to
|
||||
// support it (tautologically, as it only runs on desktop GL).
|
||||
MarkExtensionSupported(OES_rgb8_rgba8);
|
||||
}
|
||||
|
||||
if (WorkAroundDriverBugs() &&
|
||||
Vendor() == GLVendor::VMware &&
|
||||
if (Vendor() == GLVendor::VMware &&
|
||||
Renderer() == GLRenderer::GalliumLlvmpipe)
|
||||
{
|
||||
// The llvmpipe driver that is used on linux try servers appears to have
|
||||
@ -1634,8 +1674,7 @@ GLContext::InitExtensions()
|
||||
// 3000 appears to be buggy WRT updating sub-images of S3TC
|
||||
// textures with glCompressedTexSubImage2D. Works on Intel HD 4000
|
||||
// and Intel HD 5000/Iris that I tested.
|
||||
if (WorkAroundDriverBugs() &&
|
||||
nsCocoaFeatures::OSXVersionMajor() == 10 &&
|
||||
if (nsCocoaFeatures::OSXVersionMajor() == 10 &&
|
||||
nsCocoaFeatures::OSXVersionMinor() == 9 &&
|
||||
Renderer() == GLRenderer::IntelHD3000)
|
||||
{
|
||||
@ -1644,6 +1683,19 @@ GLContext::InitExtensions()
|
||||
#endif
|
||||
}
|
||||
|
||||
if (shouldDumpExts) {
|
||||
printf_stderr("\nActivated extensions:\n");
|
||||
|
||||
for (size_t i = 0; i < mAvailableExtensions.size(); i++) {
|
||||
if (!mAvailableExtensions[i])
|
||||
continue;
|
||||
|
||||
const char* ext = sExtensionNames[i];
|
||||
printf_stderr("[%i] %s\n", (uint32_t)i, ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GLContext::PlatformStartup()
|
||||
{
|
||||
@ -1688,66 +1740,6 @@ GLContext::ListHasExtension(const GLubyte *extensions, const char *extension)
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GLContext::DetermineCaps()
|
||||
{
|
||||
PixelBufferFormat format = QueryPixelFormat();
|
||||
|
||||
SurfaceCaps caps;
|
||||
caps.color = !!format.red && !!format.green && !!format.blue;
|
||||
caps.bpp16 = caps.color && format.ColorBits() == 16;
|
||||
caps.alpha = !!format.alpha;
|
||||
caps.depth = !!format.depth;
|
||||
caps.stencil = !!format.stencil;
|
||||
caps.antialias = format.samples > 1;
|
||||
caps.preserve = true;
|
||||
|
||||
mCaps = caps;
|
||||
}
|
||||
|
||||
PixelBufferFormat
|
||||
GLContext::QueryPixelFormat()
|
||||
{
|
||||
PixelBufferFormat format;
|
||||
|
||||
ScopedBindFramebuffer autoFB(this, 0);
|
||||
|
||||
fGetIntegerv(LOCAL_GL_RED_BITS , &format.red );
|
||||
fGetIntegerv(LOCAL_GL_GREEN_BITS, &format.green);
|
||||
fGetIntegerv(LOCAL_GL_BLUE_BITS , &format.blue );
|
||||
fGetIntegerv(LOCAL_GL_ALPHA_BITS, &format.alpha);
|
||||
|
||||
fGetIntegerv(LOCAL_GL_DEPTH_BITS, &format.depth);
|
||||
fGetIntegerv(LOCAL_GL_STENCIL_BITS, &format.stencil);
|
||||
|
||||
fGetIntegerv(LOCAL_GL_SAMPLES, &format.samples);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
void
|
||||
GLContext::UpdatePixelFormat()
|
||||
{
|
||||
PixelBufferFormat format = QueryPixelFormat();
|
||||
#ifdef MOZ_GL_DEBUG
|
||||
const SurfaceCaps& caps = Caps();
|
||||
MOZ_ASSERT(!caps.any, "Did you forget to DetermineCaps()?");
|
||||
|
||||
MOZ_ASSERT(caps.color == !!format.red);
|
||||
MOZ_ASSERT(caps.color == !!format.green);
|
||||
MOZ_ASSERT(caps.color == !!format.blue);
|
||||
|
||||
// These we either must have if they're requested, or
|
||||
// we can have if they're not.
|
||||
MOZ_ASSERT(caps.alpha == !!format.alpha || !caps.alpha);
|
||||
MOZ_ASSERT(caps.depth == !!format.depth || !caps.depth);
|
||||
MOZ_ASSERT(caps.stencil == !!format.stencil || !caps.stencil);
|
||||
|
||||
MOZ_ASSERT(caps.antialias == (format.samples > 1));
|
||||
#endif
|
||||
mPixelFormat = new PixelBufferFormat(format);
|
||||
}
|
||||
|
||||
GLFormats
|
||||
GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
|
||||
{
|
||||
@ -2417,6 +2409,13 @@ GLContext::FlushIfHeavyGLCallsSinceLastFlush()
|
||||
fFlush();
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
GLContext::ShouldDumpExts()
|
||||
{
|
||||
static bool ret = PR_GetEnv("MOZ_GL_DUMP_EXTS");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
DoesStringMatch(const char* aString, const char *aWantedString)
|
||||
{
|
||||
@ -2444,8 +2443,96 @@ DoesStringMatch(const char* aString, const char *aWantedString)
|
||||
/*static*/ bool
|
||||
GLContext::ShouldSpew()
|
||||
{
|
||||
static bool spew = PR_GetEnv("MOZ_GL_SPEW");
|
||||
return spew;
|
||||
static bool ret = PR_GetEnv("MOZ_GL_SPEW");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
SplitByChar(const nsACString& str, const char delim, std::vector<nsCString>* const out)
|
||||
{
|
||||
uint32_t start = 0;
|
||||
while (true) {
|
||||
int32_t end = str.FindChar(' ', start);
|
||||
if (end == -1)
|
||||
break;
|
||||
|
||||
uint32_t len = (uint32_t)end - start;
|
||||
nsDependentCSubstring substr(str, start, len);
|
||||
out->push_back(nsCString(substr));
|
||||
|
||||
start = end + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
nsDependentCSubstring substr(str, start);
|
||||
out->push_back(nsCString(substr));
|
||||
}
|
||||
|
||||
void
|
||||
GLContext::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
|
||||
{
|
||||
MOZ_ASSERT(src && dest);
|
||||
MOZ_ASSERT(dest->GetSize() == src->mSize);
|
||||
MOZ_ASSERT(dest->GetFormat() == (src->mHasAlpha ? SurfaceFormat::B8G8R8A8
|
||||
: SurfaceFormat::B8G8R8X8));
|
||||
|
||||
MakeCurrent();
|
||||
|
||||
SharedSurface* prev = GetLockedSurface();
|
||||
|
||||
const bool needsSwap = src != prev;
|
||||
if (needsSwap) {
|
||||
if (prev)
|
||||
prev->UnlockProd();
|
||||
src->LockProd();
|
||||
}
|
||||
|
||||
GLuint tempFB = 0;
|
||||
|
||||
{
|
||||
ScopedBindFramebuffer autoFB(this);
|
||||
|
||||
// Even though we're reading. We're doing it on
|
||||
// the producer side. So we call ProducerAcquire
|
||||
// instead of ConsumerAcquire.
|
||||
src->ProducerAcquire();
|
||||
|
||||
if (src->mAttachType == AttachmentType::Screen) {
|
||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
} else {
|
||||
fGenFramebuffers(1, &tempFB);
|
||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, tempFB);
|
||||
|
||||
switch (src->mAttachType) {
|
||||
case AttachmentType::GLTexture:
|
||||
fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
src->ProdTextureTarget(), src->ProdTexture(), 0);
|
||||
break;
|
||||
case AttachmentType::GLRenderbuffer:
|
||||
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
LOCAL_GL_RENDERBUFFER, src->ProdRenderbuffer());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("bad `src->mAttachType`.");
|
||||
}
|
||||
|
||||
DebugOnly<GLenum> status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
MOZ_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
|
||||
}
|
||||
|
||||
ReadPixelsIntoDataSurface(this, dest);
|
||||
|
||||
src->ProducerRelease();
|
||||
}
|
||||
|
||||
if (tempFB)
|
||||
fDeleteFramebuffers(1, &tempFB);
|
||||
|
||||
if (needsSwap) {
|
||||
src->UnlockProd();
|
||||
if (prev)
|
||||
prev->LockProd();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
|
@ -104,6 +104,7 @@ enum class GLFeature {
|
||||
get_integer_indexed,
|
||||
get_integer64_indexed,
|
||||
get_query_object_iv,
|
||||
get_string_indexed,
|
||||
gpu_shader4,
|
||||
instanced_arrays,
|
||||
instanced_non_arrays,
|
||||
@ -308,7 +309,6 @@ public:
|
||||
virtual bool IsCurrent() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
bool mInitialized;
|
||||
bool mIsOffscreen;
|
||||
bool mIsGlobalSharedContext;
|
||||
@ -325,9 +325,12 @@ protected:
|
||||
GLVendor mVendor;
|
||||
GLRenderer mRenderer;
|
||||
|
||||
inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
|
||||
MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
|
||||
MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
|
||||
void SetProfileVersion(ContextProfile profile, uint32_t version) {
|
||||
MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before"
|
||||
" initialization!");
|
||||
MOZ_ASSERT(profile != ContextProfile::Unknown &&
|
||||
profile != ContextProfile::OpenGL,
|
||||
"Invalid `profile` for SetProfileVersion");
|
||||
MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
|
||||
|
||||
mVersion = version;
|
||||
@ -457,6 +460,7 @@ public:
|
||||
return mAvailableExtensions[aKnownExtension];
|
||||
}
|
||||
|
||||
protected:
|
||||
void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
|
||||
mAvailableExtensions[aKnownExtension] = 0;
|
||||
}
|
||||
@ -465,42 +469,6 @@ public:
|
||||
mAvailableExtensions[aKnownExtension] = 1;
|
||||
}
|
||||
|
||||
public:
|
||||
template<size_t N>
|
||||
static void InitializeExtensionsBitSet(std::bitset<N>& extensionsBitset,
|
||||
const char* extStr,
|
||||
const char** extList)
|
||||
{
|
||||
char* exts = ::strdup(extStr);
|
||||
|
||||
if (ShouldSpew())
|
||||
printf_stderr("Extensions: %s\n", exts);
|
||||
|
||||
char* cur = exts;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
char* space = strchr(cur, ' ');
|
||||
if (space) {
|
||||
*space = '\0';
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
|
||||
for (int i = 0; extList[i]; ++i) {
|
||||
if (PL_strcasecmp(cur, extList[i]) == 0) {
|
||||
if (ShouldSpew())
|
||||
printf_stderr("Found extension %s\n", cur);
|
||||
extensionsBitset[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
cur = space + 1;
|
||||
}
|
||||
|
||||
free(exts);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::bitset<Extensions_Max> mAvailableExtensions;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -2022,6 +1990,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SharedSurface;
|
||||
|
||||
void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fBindFramebuffer(target, framebuffer);
|
||||
@ -3180,6 +3150,17 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// get_string_indexed
|
||||
|
||||
const GLubyte* fGetStringi(GLenum name, GLuint index) {
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fGetStringi);
|
||||
const GLubyte* ret = mSymbols.fGetStringi(name, index);
|
||||
AFTER_GL_CALL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
protected:
|
||||
@ -3448,11 +3429,9 @@ public:
|
||||
fViewport(0, 0, size.width, size.height);
|
||||
|
||||
mCaps = mScreen->mCaps;
|
||||
if (mCaps.any)
|
||||
DetermineCaps();
|
||||
MOZ_ASSERT(!mCaps.any);
|
||||
|
||||
UpdateGLFormats(mCaps);
|
||||
UpdatePixelFormat();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3475,10 +3454,8 @@ public:
|
||||
protected:
|
||||
SurfaceCaps mCaps;
|
||||
nsAutoPtr<GLFormats> mGLFormats;
|
||||
nsAutoPtr<PixelBufferFormat> mPixelFormat;
|
||||
|
||||
public:
|
||||
void DetermineCaps();
|
||||
const SurfaceCaps& Caps() const {
|
||||
return mCaps;
|
||||
}
|
||||
@ -3494,14 +3471,6 @@ public:
|
||||
return *mGLFormats;
|
||||
}
|
||||
|
||||
PixelBufferFormat QueryPixelFormat();
|
||||
void UpdatePixelFormat();
|
||||
|
||||
const PixelBufferFormat& GetPixelFormat() const {
|
||||
MOZ_ASSERT(mPixelFormat);
|
||||
return *mPixelFormat;
|
||||
}
|
||||
|
||||
bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
|
||||
|
||||
// Does not check completeness.
|
||||
@ -3541,7 +3510,7 @@ public:
|
||||
}
|
||||
|
||||
bool IsOffscreen() const {
|
||||
return !!mScreen;
|
||||
return mIsOffscreen;
|
||||
}
|
||||
|
||||
GLScreenBuffer* Screen() const {
|
||||
@ -3696,10 +3665,43 @@ protected:
|
||||
public:
|
||||
void FlushIfHeavyGLCallsSinceLastFlush();
|
||||
static bool ShouldSpew();
|
||||
static bool ShouldDumpExts();
|
||||
void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
|
||||
};
|
||||
|
||||
bool DoesStringMatch(const char* aString, const char *aWantedString);
|
||||
|
||||
void SplitByChar(const nsACString& str, const char delim,
|
||||
std::vector<nsCString>* const out);
|
||||
|
||||
template<size_t N>
|
||||
bool
|
||||
MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N],
|
||||
std::bitset<N>* const out_markList)
|
||||
{
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
if (str.Equals(markStrList[i])) {
|
||||
(*out_markList)[i] = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
void
|
||||
MarkBitfieldByStrings(const std::vector<nsCString>& strList,
|
||||
bool dumpStrings, const char* (&markStrList)[N],
|
||||
std::bitset<N>* const out_markList)
|
||||
{
|
||||
for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
|
||||
const nsACString& str = *itr;
|
||||
const bool wasMarked = MarkBitfieldByString(str, markStrList,
|
||||
out_markList);
|
||||
if (dumpStrings)
|
||||
printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
@ -28,10 +28,8 @@ class GLContextCGL : public GLContext
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, MOZ_OVERRIDE)
|
||||
GLContextCGL(const SurfaceCaps& caps,
|
||||
GLContext *shareContext,
|
||||
NSOpenGLContext *context,
|
||||
bool isOffscreen = false);
|
||||
GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
|
||||
bool isOffscreen, ContextProfile profile);
|
||||
|
||||
~GLContextCGL();
|
||||
|
||||
|
@ -274,6 +274,16 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
* ARB_occlusion_query (added by OpenGL 2.0).
|
||||
*/
|
||||
},
|
||||
{
|
||||
"get_string_indexed",
|
||||
GLVersion::GL3,
|
||||
GLESVersion::ES3,
|
||||
GLContext::Extension_None,
|
||||
{
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
// glGetStringi
|
||||
},
|
||||
{
|
||||
"gpu_shader4",
|
||||
GLVersion::GL3,
|
||||
|
@ -21,15 +21,13 @@ namespace gl {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
static bool gUseDoubleBufferedWindows = true;
|
||||
|
||||
class CGLLibrary
|
||||
{
|
||||
public:
|
||||
CGLLibrary()
|
||||
: mInitialized(false),
|
||||
mOGLLibrary(nullptr),
|
||||
mPixelFormat(nullptr)
|
||||
: mInitialized(false)
|
||||
, mUseDoubleBufferedWindows(true)
|
||||
, mOGLLibrary(nullptr)
|
||||
{}
|
||||
|
||||
bool EnsureInitialized()
|
||||
@ -46,48 +44,33 @@ public:
|
||||
}
|
||||
|
||||
const char* db = PR_GetEnv("MOZ_CGL_DB");
|
||||
gUseDoubleBufferedWindows = (!db || *db != '0');
|
||||
if (db) {
|
||||
mUseDoubleBufferedWindows = *db != '0';
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
NSOpenGLPixelFormat *PixelFormat()
|
||||
{
|
||||
if (mPixelFormat == nullptr) {
|
||||
NSOpenGLPixelFormatAttribute attribs[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAAllowOfflineRenderers,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
0
|
||||
};
|
||||
|
||||
if (!gUseDoubleBufferedWindows) {
|
||||
attribs[2] = 0;
|
||||
bool UseDoubleBufferedWindows() const {
|
||||
MOZ_ASSERT(mInitialized);
|
||||
return mUseDoubleBufferedWindows;
|
||||
}
|
||||
|
||||
mPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||
}
|
||||
|
||||
return mPixelFormat;
|
||||
}
|
||||
private:
|
||||
bool mInitialized;
|
||||
bool mUseDoubleBufferedWindows;
|
||||
PRLibrary *mOGLLibrary;
|
||||
NSOpenGLPixelFormat *mPixelFormat;
|
||||
};
|
||||
|
||||
CGLLibrary sCGLLibrary;
|
||||
|
||||
GLContextCGL::GLContextCGL(
|
||||
const SurfaceCaps& caps,
|
||||
GLContext *shareContext,
|
||||
NSOpenGLContext *context,
|
||||
bool isOffscreen)
|
||||
: GLContext(caps, shareContext, isOffscreen),
|
||||
mContext(context)
|
||||
GLContextCGL::GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
|
||||
bool isOffscreen, ContextProfile profile)
|
||||
: GLContext(caps, nullptr, isOffscreen)
|
||||
, mContext(context)
|
||||
{
|
||||
SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
|
||||
SetProfileVersion(profile, 210);
|
||||
}
|
||||
|
||||
GLContextCGL::~GLContextCGL()
|
||||
@ -162,7 +145,7 @@ GLContextCGL::SetupLookupFunction()
|
||||
bool
|
||||
GLContextCGL::IsDoubleBuffered() const
|
||||
{
|
||||
return gUseDoubleBufferedWindows;
|
||||
return sCGLLibrary.UseDoubleBufferedWindows();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -182,26 +165,66 @@ GLContextCGL::SwapBuffers()
|
||||
}
|
||||
|
||||
|
||||
static GLContextCGL *
|
||||
GetGlobalContextCGL()
|
||||
{
|
||||
return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateWrappingExisting(void*, void*)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAAllowOfflineRenderers,
|
||||
0
|
||||
};
|
||||
|
||||
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAAllowOfflineRenderers,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
0
|
||||
};
|
||||
|
||||
static const NSOpenGLPixelFormatAttribute kAttribs_offscreen[] = {
|
||||
NSOpenGLPFAPixelBuffer,
|
||||
0
|
||||
};
|
||||
|
||||
static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_coreProfile[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||
0
|
||||
};
|
||||
|
||||
static NSOpenGLContext*
|
||||
CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
|
||||
{
|
||||
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]
|
||||
initWithAttributes:attribs];
|
||||
if (!format)
|
||||
return nullptr;
|
||||
|
||||
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
|
||||
shareContext:nullptr];
|
||||
|
||||
[format release];
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
|
||||
{
|
||||
GLContextCGL *shareContext = GetGlobalContextCGL();
|
||||
if (!sCGLLibrary.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NSOpenGLContext *context = [[NSOpenGLContext alloc]
|
||||
initWithFormat:sCGLLibrary.PixelFormat()
|
||||
shareContext:(shareContext ? shareContext->mContext : NULL)];
|
||||
const NSOpenGLPixelFormatAttribute* attribs;
|
||||
if (sCGLLibrary.UseDoubleBufferedWindows()) {
|
||||
attribs = kAttribs_doubleBuffered;
|
||||
} else {
|
||||
attribs = kAttribs_singleBuffered;
|
||||
}
|
||||
NSOpenGLContext* context = CreateWithFormat(attribs);
|
||||
if (!context) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -211,10 +234,13 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
|
||||
[context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
|
||||
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps,
|
||||
shareContext,
|
||||
context);
|
||||
ContextProfile profile = ContextProfile::OpenGLCompatibility;
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps, context, false,
|
||||
profile);
|
||||
|
||||
if (!glContext->Init()) {
|
||||
glContext = nullptr;
|
||||
[context release];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -222,49 +248,54 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextCGL>
|
||||
CreateOffscreenFBOContext(bool aShare = true)
|
||||
CreateOffscreenFBOContext(bool requireCompatProfile)
|
||||
{
|
||||
if (!sCGLLibrary.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
|
||||
if (aShare && !shareContext) {
|
||||
// if there is no share context, then we can't use FBOs.
|
||||
return nullptr;
|
||||
}
|
||||
ContextProfile profile;
|
||||
NSOpenGLContext* context = nullptr;
|
||||
|
||||
NSOpenGLContext *context = [[NSOpenGLContext alloc]
|
||||
initWithFormat:sCGLLibrary.PixelFormat()
|
||||
shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL];
|
||||
if (!requireCompatProfile) {
|
||||
profile = ContextProfile::OpenGLCore;
|
||||
context = CreateWithFormat(kAttribs_offscreen_coreProfile);
|
||||
}
|
||||
if (!context) {
|
||||
profile = ContextProfile::OpenGLCompatibility;
|
||||
context = CreateWithFormat(kAttribs_offscreen);
|
||||
}
|
||||
if (!context) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, context,
|
||||
true, profile);
|
||||
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateHeadless()
|
||||
GLContextProviderCGL::CreateHeadless(bool requireCompatProfile)
|
||||
{
|
||||
nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
|
||||
if (!glContext)
|
||||
nsRefPtr<GLContextCGL> gl;
|
||||
gl = CreateOffscreenFBOContext(requireCompatProfile);
|
||||
if (!gl)
|
||||
return nullptr;
|
||||
|
||||
if (!glContext->Init())
|
||||
if (!gl->Init())
|
||||
return nullptr;
|
||||
|
||||
return glContext.forget();
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps)
|
||||
const SurfaceCaps& caps,
|
||||
bool requireCompatProfile)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless();
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
|
||||
if (!glContext->InitOffscreen(ToIntSize(size), caps))
|
||||
return nullptr;
|
||||
|
||||
|
@ -878,7 +878,7 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& size)
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderEGL::CreateHeadless()
|
||||
GLContextProviderEGL::CreateHeadless(bool)
|
||||
{
|
||||
if (!sEGLLibrary.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
@ -897,9 +897,10 @@ GLContextProviderEGL::CreateHeadless()
|
||||
// often without the ability to texture from them directly.
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps)
|
||||
const SurfaceCaps& caps,
|
||||
bool requireCompatProfile)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless();
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
|
||||
if (!glContext)
|
||||
return nullptr;
|
||||
|
||||
|
@ -1215,7 +1215,7 @@ DONE_CREATING_PIXMAP:
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderGLX::CreateHeadless()
|
||||
GLContextProviderGLX::CreateHeadless(bool)
|
||||
{
|
||||
gfxIntSize dummySize = gfxIntSize(16, 16);
|
||||
nsRefPtr<GLContext> glContext = CreateOffscreenPixmapContext(dummySize);
|
||||
@ -1227,9 +1227,10 @@ GLContextProviderGLX::CreateHeadless()
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps)
|
||||
const SurfaceCaps& caps,
|
||||
bool requireCompatProfile)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless();
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
|
||||
if (!glContext)
|
||||
return nullptr;
|
||||
|
||||
|
@ -58,11 +58,12 @@ public:
|
||||
*/
|
||||
static already_AddRefed<GLContext>
|
||||
CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps);
|
||||
const SurfaceCaps& caps,
|
||||
bool requireCompatProfile);
|
||||
|
||||
// Just create a context. We'll add offscreen stuff ourselves.
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadless();
|
||||
CreateHeadless(bool requireCompatProfile);
|
||||
|
||||
/**
|
||||
* Create wrapping Gecko GLContext for external gl context.
|
||||
|
@ -22,13 +22,14 @@ GLContextProviderNull::CreateWrappingExisting(void*, void*)
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
|
||||
const SurfaceCaps&)
|
||||
const SurfaceCaps&,
|
||||
bool)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderNull::CreateHeadless()
|
||||
GLContextProviderNull::CreateHeadless(bool)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -607,7 +607,7 @@ CreateWindowOffscreenContext()
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderWGL::CreateHeadless()
|
||||
GLContextProviderWGL::CreateHeadless(bool)
|
||||
{
|
||||
if (!sWGLLib.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
@ -641,9 +641,10 @@ GLContextProviderWGL::CreateHeadless()
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps)
|
||||
const SurfaceCaps& caps,
|
||||
bool requireCompatProfile)
|
||||
{
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless();
|
||||
nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
|
||||
if (!glContext)
|
||||
return nullptr;
|
||||
|
||||
|
@ -666,6 +666,10 @@ struct GLContextSymbols
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE3D fCompressedTexSubImage3D;
|
||||
|
||||
// get_string_indexed
|
||||
typedef const GLubyte* (GLAPIENTRY * pfnGLGetStringiT)(GLenum name, GLuint index);
|
||||
pfnGLGetStringiT fGetStringi;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,8 +12,3 @@ GLFormats::GLFormats()
|
||||
{
|
||||
std::memset(this, 0, sizeof(GLFormats));
|
||||
}
|
||||
|
||||
PixelBufferFormat::PixelBufferFormat()
|
||||
{
|
||||
std::memset(this, 0, sizeof(PixelBufferFormat));
|
||||
}
|
||||
|
@ -43,19 +43,6 @@ struct GLFormats
|
||||
GLsizei samples;
|
||||
};
|
||||
|
||||
struct PixelBufferFormat
|
||||
{
|
||||
// Constructs a zeroed object:
|
||||
PixelBufferFormat();
|
||||
|
||||
int red, green, blue;
|
||||
int alpha;
|
||||
int depth, stencil;
|
||||
int samples;
|
||||
|
||||
int ColorBits() const { return red + green + blue; }
|
||||
};
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
@ -35,8 +35,7 @@ static const char *sEGLExtensionNames[] = {
|
||||
"EGL_EXT_create_context_robustness",
|
||||
"EGL_KHR_image",
|
||||
"EGL_KHR_fence_sync",
|
||||
"EGL_ANDROID_native_fence_sync",
|
||||
nullptr
|
||||
"EGL_ANDROID_native_fence_sync"
|
||||
};
|
||||
|
||||
#if defined(ANDROID)
|
||||
@ -240,8 +239,8 @@ GLLibraryEGL::EnsureInitialized()
|
||||
};
|
||||
|
||||
// Do not warn about the failure to load this - see bug 1092191
|
||||
GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0],
|
||||
nullptr, nullptr, false);
|
||||
GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
|
||||
false);
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
|
||||
MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
|
||||
@ -421,15 +420,24 @@ GLLibraryEGL::EnsureInitialized()
|
||||
void
|
||||
GLLibraryEGL::InitExtensions()
|
||||
{
|
||||
const char *extensions = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
|
||||
std::vector<nsCString> driverExtensionList;
|
||||
|
||||
if (!extensions) {
|
||||
const char* rawExts = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
|
||||
if (rawExts) {
|
||||
nsDependentCString exts(rawExts);
|
||||
SplitByChar(exts, ' ', &driverExtensionList);
|
||||
} else {
|
||||
NS_WARNING("Failed to load EGL extension list!");
|
||||
return;
|
||||
}
|
||||
|
||||
GLContext::InitializeExtensionsBitSet(mAvailableExtensions, extensions,
|
||||
sEGLExtensionNames);
|
||||
const bool shouldDumpExts = GLContext::ShouldDumpExts();
|
||||
if (shouldDumpExts) {
|
||||
printf_stderr("%i EGL driver extensions: (*: recognized)\n",
|
||||
(uint32_t)driverExtensionList.size());
|
||||
}
|
||||
|
||||
MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sEGLExtensionNames,
|
||||
&mAvailableExtensions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
|
@ -517,43 +517,6 @@ GLScreenBuffer::CreateRead(SharedSurface* surf)
|
||||
return ReadBuffer::Create(gl, caps, formats, surf);
|
||||
}
|
||||
|
||||
void
|
||||
GLScreenBuffer::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
|
||||
{
|
||||
MOZ_ASSERT(src && dest);
|
||||
MOZ_ASSERT(dest->GetSize() == src->mSize);
|
||||
MOZ_ASSERT(dest->GetFormat() == (src->mHasAlpha ? SurfaceFormat::B8G8R8A8
|
||||
: SurfaceFormat::B8G8R8X8));
|
||||
|
||||
mGL->MakeCurrent();
|
||||
|
||||
bool needsSwap = src != SharedSurf();
|
||||
if (needsSwap) {
|
||||
SharedSurf()->UnlockProd();
|
||||
src->LockProd();
|
||||
}
|
||||
|
||||
{
|
||||
// Even though we're reading. We're doing it on
|
||||
// the producer side. So we call ProducerAcquire
|
||||
// instead of ConsumerAcquire.
|
||||
src->ProducerAcquire();
|
||||
|
||||
UniquePtr<ReadBuffer> buffer = CreateRead(src);
|
||||
MOZ_ASSERT(buffer);
|
||||
|
||||
ScopedBindFramebuffer autoFB(mGL, buffer->mFB);
|
||||
ReadPixelsIntoDataSurface(mGL, dest);
|
||||
|
||||
src->ProducerRelease();
|
||||
}
|
||||
|
||||
if (needsSwap) {
|
||||
src->UnlockProd();
|
||||
SharedSurf()->LockProd();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GLScreenBuffer::IsDrawFramebufferDefault() const
|
||||
{
|
||||
|
@ -245,8 +245,6 @@ public:
|
||||
|
||||
bool Resize(const gfx::IntSize& size);
|
||||
|
||||
void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
|
||||
|
||||
protected:
|
||||
bool Attach(SharedSurface* surf, const gfx::IntSize& size);
|
||||
|
||||
|
@ -135,7 +135,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
||||
if (destSize == readSize && destFormat == format) {
|
||||
RefPtr<DataSourceSurface> data =
|
||||
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
|
||||
mGLContext->Screen()->Readback(frontbuffer, data);
|
||||
mGLContext->Readback(frontbuffer, data);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
}
|
||||
@ -154,7 +154,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Screen()->Readback(frontbuffer, resultSurf);
|
||||
mGLContext->Readback(frontbuffer, resultSurf);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ GLImage::GetAsSourceSurface()
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
|
||||
|
||||
if (!sSnapshotContext) {
|
||||
sSnapshotContext = GLContextProvider::CreateHeadless();
|
||||
sSnapshotContext = GLContextProvider::CreateHeadless(false);
|
||||
if (!sSnapshotContext) {
|
||||
NS_WARNING("Failed to create snapshot GLContext");
|
||||
return nullptr;
|
||||
|
@ -124,8 +124,11 @@ CompositorOGL::CreateContext()
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGB();
|
||||
caps.preserve = false;
|
||||
caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565;
|
||||
|
||||
bool requireCompatProfile = true;
|
||||
context = GLContextProvider::CreateOffscreen(gfxIntSize(mSurfaceSize.width,
|
||||
mSurfaceSize.height), caps);
|
||||
mSurfaceSize.height),
|
||||
caps, requireCompatProfile);
|
||||
}
|
||||
|
||||
if (!context)
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
caps.preserve = false;
|
||||
caps.bpp16 = false;
|
||||
nsRefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
|
||||
gfxIntSize(gCompWidth, gCompHeight), caps);
|
||||
gfxIntSize(gCompWidth, gCompHeight), caps, true);
|
||||
return context.forget().take();
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1097,8 +1097,9 @@ gfxPlatform::GetSkiaGLGlue()
|
||||
* FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it
|
||||
* stands, this only works on the main thread.
|
||||
*/
|
||||
mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGBA();
|
||||
nsRefPtr<mozilla::gl::GLContext> glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
|
||||
bool requireCompatProfile = true;
|
||||
nsRefPtr<mozilla::gl::GLContext> glContext;
|
||||
glContext = mozilla::gl::GLContextProvider::CreateHeadless(requireCompatProfile);
|
||||
if (!glContext) {
|
||||
printf_stderr("Failed to create GLContext for SkiaGL!\n");
|
||||
return nullptr;
|
||||
|
@ -72,8 +72,8 @@ public:
|
||||
}
|
||||
|
||||
nsRefPtr<gl::GLContext> gl;
|
||||
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16),
|
||||
gl::SurfaceCaps::ForRGB());
|
||||
bool requireCompatProfile = true;
|
||||
gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
|
||||
|
||||
if (!gl) {
|
||||
// Setting mReady to true here means that we won't retry. Everything will
|
||||
|
Loading…
Reference in New Issue
Block a user