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
parent cb3b122036
commit 433dc416ec
7 changed files with 106 additions and 38 deletions

View File

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

View File

@ -97,6 +97,7 @@ static const char *sExtensionNames[] = {
"GL_ARB_map_buffer_range",
"GL_ARB_occlusion_query2",
"GL_ARB_pixel_buffer_object",
"GL_ARB_robust_buffer_access_behavior",
"GL_ARB_robustness",
"GL_ARB_sampler_objects",
"GL_ARB_sync",
@ -148,6 +149,7 @@ static const char *sExtensionNames[] = {
"GL_IMG_texture_compression_pvrtc",
"GL_IMG_texture_npot",
"GL_KHR_debug",
"GL_KHR_robust_buffer_access_behavior",
"GL_NV_draw_instanced",
"GL_NV_fence",
"GL_NV_framebuffer_blit",
@ -1642,6 +1644,19 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
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();
} else {
// if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs

View File

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

View File

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

View File

@ -505,6 +505,17 @@ static const FeatureInfo sFeatureInfoArr[] = {
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",
GLVersion::NONE,
@ -831,6 +842,12 @@ GLContext::InitFeatures()
}
}
void
GLContext::MarkSupported(GLFeature feature)
{
mAvailableFeatures[size_t(feature)] = true;
}
void
GLContext::MarkUnsupported(GLFeature feature)
{

View File

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

View File

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