Bug 1200864 - Skip DrawElements buffer validation when we have robust_buffer_access. - r=kamidphish

This commit is contained in:
Jeff Gilbert 2015-09-02 14:06:58 -07:00
Родитель c9b205eede
Коммит f2508b4907
7 изменённых файлов: 106 добавлений и 38 удалений

Просмотреть файл

@ -254,14 +254,19 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type,
if (!ValidateBufferFetching(info)) if (!ValidateBufferFetching(info))
return false; return false;
if (gl->IsSupported(GLFeature::robust_buffer_access_behavior)) {
*out_upperBound = 0;
} else {
if (!mMaxFetchedVertices || if (!mMaxFetchedVertices ||
!elemArrayBuffer.Validate(type, mMaxFetchedVertices - 1, first, count, out_upperBound)) !elemArrayBuffer.Validate(type, mMaxFetchedVertices - 1, first, count,
out_upperBound))
{ {
ErrorInvalidOperation( ErrorInvalidOperation(
"%s: bound vertex attribute buffers do not have sufficient " "%s: bound vertex attribute buffers do not have sufficient "
"size for given indices from the bound element array", info); "size for given indices from the bound element array", info);
return false; return false;
} }
}
if (uint32_t(primcount) > mMaxFetchedInstances) { if (uint32_t(primcount) > mMaxFetchedInstances) {
ErrorInvalidOperation("%s: bound instance attribute buffers do not have sufficient size for given primcount", info); ErrorInvalidOperation("%s: bound instance attribute buffers do not have sufficient size for given primcount", info);
@ -322,7 +327,7 @@ WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
{ {
ScopedMaskWorkaround autoMask(*this); ScopedMaskWorkaround autoMask(*this);
if (gl->IsSupported(gl::GLFeature::draw_range_elements)) { if (upperBound && gl->IsSupported(gl::GLFeature::draw_range_elements)) {
gl->fDrawRangeElements(mode, 0, upperBound, count, type, gl->fDrawRangeElements(mode, 0, upperBound, count, type,
reinterpret_cast<GLvoid*>(byteOffset)); reinterpret_cast<GLvoid*>(byteOffset));
} else { } else {

Просмотреть файл

@ -97,6 +97,7 @@ static const char *sExtensionNames[] = {
"GL_ARB_map_buffer_range", "GL_ARB_map_buffer_range",
"GL_ARB_occlusion_query2", "GL_ARB_occlusion_query2",
"GL_ARB_pixel_buffer_object", "GL_ARB_pixel_buffer_object",
"GL_ARB_robust_buffer_access_behavior",
"GL_ARB_robustness", "GL_ARB_robustness",
"GL_ARB_sampler_objects", "GL_ARB_sampler_objects",
"GL_ARB_sync", "GL_ARB_sync",
@ -148,6 +149,7 @@ static const char *sExtensionNames[] = {
"GL_IMG_texture_compression_pvrtc", "GL_IMG_texture_compression_pvrtc",
"GL_IMG_texture_npot", "GL_IMG_texture_npot",
"GL_KHR_debug", "GL_KHR_debug",
"GL_KHR_robust_buffer_access_behavior",
"GL_NV_draw_instanced", "GL_NV_draw_instanced",
"GL_NV_fence", "GL_NV_fence",
"GL_NV_framebuffer_blit", "GL_NV_framebuffer_blit",
@ -1642,6 +1644,19 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
true); true);
} }
// Until ANGLE supports robust_buffer_access_behavior explicitly, we'll need to
// add it ourselves for D3D10+. (D3D10+ always supports
// robust_buffer_access_behavior)
if (IsANGLE()) {
const char* renderer = (const char*)fGetString(LOCAL_GL_RENDERER);
if (strstr(renderer, "Direct3D10") || strstr(renderer, "Direct3D11")) {
MOZ_ASSERT(!IsSupported(GLFeature::robust_buffer_access_behavior),
"Since ANGLE supports robust_buffer_access_behavior now, we can"
" remove this block of code.");
MarkSupported(GLFeature::robust_buffer_access_behavior);
}
}
reporter.SetSuccessful(); reporter.SetSuccessful();
} else { } else {
// if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs // if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs

Просмотреть файл

@ -119,6 +119,7 @@ enum class GLFeature {
read_buffer, read_buffer,
renderbuffer_color_float, renderbuffer_color_float,
renderbuffer_color_half_float, renderbuffer_color_half_float,
robust_buffer_access_behavior,
robustness, robustness,
sRGB_framebuffer, sRGB_framebuffer,
sRGB_texture, sRGB_texture,
@ -407,6 +408,7 @@ public:
ARB_map_buffer_range, ARB_map_buffer_range,
ARB_occlusion_query2, ARB_occlusion_query2,
ARB_pixel_buffer_object, ARB_pixel_buffer_object,
ARB_robust_buffer_access_behavior,
ARB_robustness, ARB_robustness,
ARB_sampler_objects, ARB_sampler_objects,
ARB_sync, ARB_sync,
@ -458,6 +460,7 @@ public:
IMG_texture_compression_pvrtc, IMG_texture_compression_pvrtc,
IMG_texture_npot, IMG_texture_npot,
KHR_debug, KHR_debug,
KHR_robust_buffer_access_behavior,
NV_draw_instanced, NV_draw_instanced,
NV_fence, NV_fence,
NV_framebuffer_blit, NV_framebuffer_blit,
@ -527,6 +530,8 @@ private:
*/ */
void InitFeatures(); void InitFeatures();
void MarkSupported(GLFeature feature);
/** /**
* Mark the feature and associated extensions as unsupported * Mark the feature and associated extensions as unsupported
*/ */
@ -3614,6 +3619,10 @@ public:
static bool ShouldSpew(); static bool ShouldSpew();
static bool ShouldDumpExts(); static bool ShouldDumpExts();
void Readback(SharedSurface* src, gfx::DataSourceSurface* dest); void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
virtual bool NeedsDrawElementsValidation() const {
return true;
}
}; };
bool DoesStringMatch(const char* aString, const char *aWantedString); bool DoesStringMatch(const char* aString, const char *aWantedString);

Просмотреть файл

@ -70,6 +70,10 @@ public:
return sEGLLibrary.IsWARP(); return sEGLLibrary.IsWARP();
} }
virtual bool NeedsDrawElementsValidation() const override {
return true;
}
virtual bool BindTexImage() override; virtual bool BindTexImage() override;
virtual bool ReleaseTexImage() override; virtual bool ReleaseTexImage() override;

Просмотреть файл

@ -505,6 +505,17 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End GLContext::Extensions_End
} }
}, },
{
"robust_buffer_access_behavior",
GLVersion::NONE,
GLESVersion::NONE,
GLContext::Extension_None,
{
GLContext::ARB_robust_buffer_access_behavior,
GLContext::KHR_robust_buffer_access_behavior,
GLContext::Extensions_End
}
},
{ {
"robustness", "robustness",
GLVersion::NONE, GLVersion::NONE,
@ -831,6 +842,12 @@ GLContext::InitFeatures()
} }
} }
void
GLContext::MarkSupported(GLFeature feature)
{
mAvailableFeatures[size_t(feature)] = true;
}
void void
GLContext::MarkUnsupported(GLFeature feature) GLContext::MarkUnsupported(GLFeature feature)
{ {

Просмотреть файл

@ -137,19 +137,25 @@ CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget);
#define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \ #define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \
LOCAL_EGL_NONE, 0, 0, 0 LOCAL_EGL_NONE, 0, 0, 0
static EGLint gTerminationAttribs[] = { static EGLint kTerminationAttribs[] = {
EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
}; };
static EGLint gContextAttribs[] = { static EGLint kContextAttribs[] = {
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2, LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
}; };
static EGLint gContextAttribsRobustness[] = { static EGLint kContextAttribsRobustness[] = {
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2, LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
//LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE, LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT, EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
};
static EGLint kContextAttribsRobustAccess[] = {
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE,
LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
}; };
@ -501,6 +507,29 @@ GLContextEGL::DestroySurface(EGLSurface aSurface)
} }
} }
static EGLContext
CreateContextForShareContext(EGLDisplay display, EGLConfig config,
EGLContext shareContext)
{
EGLContext context = nullptr;
if (sEGLLibrary.HasRobustness()) {
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, shareContext,
kContextAttribsRobustAccess);
if (!context) {
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, shareContext,
kContextAttribsRobustness);
}
}
if (!context) {
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, shareContext,
kContextAttribs);
}
return context;
}
already_AddRefed<GLContextEGL> already_AddRefed<GLContextEGL>
GLContextEGL::CreateGLContext(const SurfaceCaps& caps, GLContextEGL::CreateGLContext(const SurfaceCaps& caps,
GLContextEGL *shareContext, GLContextEGL *shareContext,
@ -513,34 +542,24 @@ GLContextEGL::CreateGLContext(const SurfaceCaps& caps,
return nullptr; return nullptr;
} }
EGLContext eglShareContext = shareContext ? shareContext->mContext EGLContext context = nullptr;
: EGL_NO_CONTEXT; if (shareContext) {
EGLint* attribs = sEGLLibrary.HasRobustness() ? gContextAttribsRobustness context = CreateContextForShareContext(EGL_DISPLAY(), config,
: gContextAttribs; shareContext->mContext);
EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
config,
eglShareContext,
attribs);
if (!context && shareContext) {
shareContext = nullptr;
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
config,
EGL_NO_CONTEXT,
attribs);
} }
if (!context) {
shareContext = nullptr;
context = CreateContextForShareContext(EGL_DISPLAY(), config, nullptr);
}
if (!context) { if (!context) {
NS_WARNING("Failed to create EGLContext!"); NS_WARNING("Failed to create EGLContext!");
return nullptr; return nullptr;
} }
nsRefPtr<GLContextEGL> glContext = new GLContextEGL(caps, nsRefPtr<GLContextEGL> glContext = new GLContextEGL(caps, shareContext, isOffscreen,
shareContext, config, surface, context);
isOffscreen,
config,
surface,
context);
if (!glContext->Init()) if (!glContext->Init())
return nullptr; return nullptr;
@ -568,8 +587,8 @@ TRY_AGAIN_POWER_OF_TWO:
pbattrs.AppendElement(bindToTextureFormat); pbattrs.AppendElement(bindToTextureFormat);
} }
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) { for (size_t i = 0; i < MOZ_ARRAY_LENGTH(kTerminationAttribs); i++) {
pbattrs.AppendElement(gTerminationAttribs[i]); pbattrs.AppendElement(kTerminationAttribs[i]);
} }
surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]); surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);

Просмотреть файл

@ -52,7 +52,6 @@
// Others // Others
#define LOCAL_EGL_PRESERVED_RESOURCES 0x3030 #define LOCAL_EGL_PRESERVED_RESOURCES 0x3030
#define LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
// ANGLE_platform_angle_d3d // ANGLE_platform_angle_d3d
#define LOCAL_EGL_PLATFORM_ANGLE_ANGLE 0x3201 #define LOCAL_EGL_PLATFORM_ANGLE_ANGLE 0x3201