Closed Bug 958256 Opened 10 years ago Closed 10 years ago

Canvas2D demo triggers Skia/GL asserts as a shader fails to compile on Vivante GC1000

Categories

(Core :: Graphics, defect)

ARM
Android
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla29

People

(Reporter: bjacob, Assigned: bjacob)

Details

Attachments

(1 file)

STR:
 1. Make a debug build of Fennec
 2. Run on a Galaxy Tab 3 (or perhaps other devices with a Vivante GC1000 GPU)
 3. Browse to this URL: http://www.smashcat.org/av/canvas_test/

Result: crash, assert failure inside of Skia/GL.

Logcat:

D/GeckoToolbar(26217): onTabChanged: LOADED
D/GeckoBrowserApp(26217): BrowserApp.onTabChanged: 0: LOADED
W/GeckoGlobalHistory(26217): Rebuilding visited link set...
I/Gecko   (26217): Enter: void mozilla::AndroidBridge::GetDisplayPort(bool, bool, int32_t, nsIAndroidViewport*, nsIAndroidDisplayport**)
I/Gecko   (26217): Exit: void mozilla::AndroidBridge::GetDisplayPort(bool, bool, int32_t, nsIAndroidViewport*, nsIAndroidDisplayport**)
D/GC      (26217): <tid=26286> OES20 ===> GC Version   : GC Ver-988-JB-R4-RC2-GC20 
D/GC      (26217): 
I/Gecko   (26217): Initializing context 0x627d23a8 surface 0x627e8c80 on display 0x1
I/Gecko   (26217): OpenGL version detected: 200
I/Gecko   (26217): OpenGL vendor: Vivante Corporation
I/Gecko   (26217): OpenGL renderer: GC1000 core
E/LightSensor(  380): LightSensor::readEvents mPendingEvent.light = 276
I/Gecko   (26217): Exported SkiaGL extensions: GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_texture_npot GL_OES_standard_derivatives GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra 
E/LightSensor(  380): LightSensor::readEvents mPendingEvent.light = 276
D/GC      (26217): <tid=26286> OES20 ===> GC Version   : GC Ver-988-JB-R4-RC2-GC20 
D/GC      (26217): 
I/Gecko   (26217): Initializing context 0x5a67e758 surface 0x716981e8 on display 0x1
I/Gecko   (26217): OpenGL version detected: 200
I/Gecko   (26217): OpenGL vendor: Vivante Corporation
I/Gecko   (26217): OpenGL renderer: GC1000 core
D/v_gal   (26217): [tid=26286] gcmONERROR: status=-2000(nil) @ ppoPREPROCESSOR_Extension(2049)
D/v_gal   (26217): [tid=26286] gcmONERROR: status=-2000(nil) @ ppoPREPROCESSOR_Group(262)
D/v_gal   (26217): [tid=26286] gcmONERROR: status=-2000(nil) @ ppoPREPROCESSOR_Parse(1141)
D/v_gal   (26217): [tid=26286] gcmONERROR: status=-2001(nil) @ gcCompileShader(293)
D/skia    (26217): #version 100
D/skia    (26217): #extension GL_OES_standard_derivatives: require
D/skia    (26217): precision mediump float;
D/skia    (26217): varying vec4 vColor;
D/skia    (26217): varying vec4 vQuadEdge4;
D/skia    (26217): void main() {
D/skia    (26217):      vec4 color4;
D/skia    (26217):      { // QuadEdge 
D/skia    (26217):              float edgeAlpha;
D/skia    (26217):              vec2 duvdx = dFdx(vQuadEdge4.xy);
D/skia    (26217):              vec2 duvdy = dFdy(vQuadEdge4.xy);
D/skia    (26217):              if (vQuadEdge4.z > 0.0 && vQuadEdge4.w > 0.0) {
D/skia    (26217):                      edgeAlpha = min(min(vQuadEdge4.z, vQuadEdge4.w) + 0.5, 1.0);
D/skia    (26217):              } else {
D/skia    (26217):                      vec2 gF = vec2(2.0*vQuadEdge4.x*duvdx.x - duvdx.y,
D/skia    (26217):                                     2.0*vQuadEdge4.x*duvdy.x - duvdy.y);
D/skia    (26217):                      edgeAlpha = (vQuadEdge4.x*vQuadEdge4.x - vQuadEdge4.y);
D/skia    (26217):                      edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
D/skia    (26217):              }
D/skia    (26217):      color4 = vec4(vColor * edgeAlpha);
D/skia    (26217):      }
D/skia    (26217):      gl_FragColor = vec4(color4);
D/skia    (26217): }
D/skia    (26217): 
D/skia    (26217): (3:0) : error : Extension GL_OES_standard_derivatives does not support 'require'.
D/skia    (26217): (3:0) : error : Error in parsing.
D/skia    (26217): (15:0) : error : syntax error
D/skia    (26217): /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp(361) :  !"Shader compilation failed!" 


C++ callstack:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 26286]
compile_shader (stringLengths=0x625e6610, strings=0x625e660c, type=<optimized out>, gl=..., 
    stringCnt=<optimized out>) at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:361
361             GrAssert(!"Shader compilation failed!");
Loading symbols... Done
(gdb) bt
#0  compile_shader (stringLengths=0x625e6610, strings=0x625e660c, type=<optimized out>, gl=..., 
    stringCnt=<optimized out>) at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:361
#1  (anonymous namespace)::compile_shader (gl=..., type=type@entry=35632, shader=...)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:372
#2  0x6872ab4e in GrGLProgram::compileShaders (this=this@entry=0x70f5fe00, builder=...)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:411
#3  0x6872db58 in GrGLProgram::genProgram (this=this@entry=0x70f5fe00, stages=stages@entry=0x625e6b48)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:662
#4  0x6872de46 in GrGLProgram::GrGLProgram (this=0x70f5fe00, gl=..., desc=..., stages=0x625e6b48)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:67
#5  0x6872de98 in GrGLProgram::Create (gl=..., desc=..., stages=0x625e6b48)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGLProgram.cpp:41
#6  0x68738896 in GrGpuGL::ProgramCache::getProgram (this=0x6fae2000, desc=..., stages=stages@entry=0x625e6b48)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGpuGL_program.cpp:64
#7  0x68738a30 in GrGpuGL::flushGraphicsState (this=0x718e3800, type=GrGpu::kDrawTriangles_DrawType, dstCopy=0x0)
    at /hack/mozilla-central/gfx/skia/src/gpu/gl/GrGpuGL_program.cpp:193
#8  0x68714280 in setupClipAndFlushState (dstCopy=0x0, type=GrGpu::kDrawTriangles_DrawType, this=0x718e3800)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrGpu.cpp:339
#9  GrGpu::setupClipAndFlushState (this=0x718e3800, type=GrGpu::kDrawTriangles_DrawType, dstCopy=0x0)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrGpu.cpp:333
#10 0x6871432c in GrGpu::onDraw (this=0x718e3800, info=...)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrGpu.cpp:378
#11 0x68711c76 in executeDraw (info=..., this=<optimized out>)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrDrawTarget.h:424
#12 GrInOrderDrawBuffer::flush (this=this@entry=0x70268000)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrInOrderDrawBuffer.cpp:468
#13 0x68711f20 in GrInOrderDrawBuffer::willReserveVertexAndIndexSpace (this=0x70268000, vertexCount=36, 
    indexCount=60) at /hack/mozilla-central/gfx/skia/src/gpu/GrInOrderDrawBuffer.cpp:542
#14 0x6870e75e in GrDrawTarget::reserveVertexAndIndexSpace (this=this@entry=0x70268000, 
    vertexCount=vertexCount@entry=36, indexCount=indexCount@entry=60, vertices=vertices@entry=0x625e72a0, 
    indices=indices@entry=0x625e72a4) at /hack/mozilla-central/gfx/skia/src/gpu/GrDrawTarget.cpp:198
#15 0x6870e7c8 in GrDrawTarget::AutoReleaseGeometry::set (this=0x625e729c, target=0x70268000, vertexCount=36, 
    indexCount=60) at /hack/mozilla-central/gfx/skia/src/gpu/GrDrawTarget.cpp:731
#16 0x6870e81c in GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry (this=0x625e729c, 
    target=<optimized out>, vertexCount=<optimized out>, indexCount=<optimized out>)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrDrawTarget.cpp:709
#17 0x68707b8a in GrAAConvexPathRenderer::onDrawPath (origPath=..., target=0x70268000, antiAlias=<optimized out>, 
    this=<optimized out>) at /hack/mozilla-central/gfx/skia/src/gpu/GrAAConvexPathRenderer.cpp:623
#18 0x68709e32 in GrPathRenderer::drawPath (this=0x71771130, path=..., stroke=..., target=0x70268000, 
    antiAlias=true) at /hack/mozilla-central/gfx/skia/src/gpu/GrPathRenderer.h:123
#19 0x6870c434 in GrContext::internalDrawPath (this=this@entry=0x70e72e20, target=target@entry=0x70268000, 
    paint=..., path=..., stroke=...) at /hack/mozilla-central/gfx/skia/src/gpu/GrContext.cpp:1070
#20 0x687124a0 in GrContext::drawPath (this=0x70e72e20, paint=..., path=..., stroke=...)
    at /hack/mozilla-central/gfx/skia/src/gpu/GrContext.cpp:1021
#21 0x68723e12 in SkGpuDevice::drawPath (this=0x6fa2f400, draw=..., origSrcPath=..., paint=..., 
    prePathMatrix=0x50ff8001, pathIsMutable=false) at /hack/mozilla-central/gfx/skia/src/gpu/SkGpuDevice.cpp:1066
#22 0x686b209a in SkCanvas::drawPath (this=0x6fe6be10, path=..., paint=...)
    at /hack/mozilla-central/gfx/skia/src/core/SkCanvas.cpp:1617
#23 0x686159a2 in Fill (aOptions=..., aPattern=..., aPath=0x6f1812c0, this=0x70e72dc0)
    at /hack/mozilla-central/gfx/2d/DrawTargetSkia.cpp:560
#24 mozilla::gfx::DrawTargetSkia::Fill (this=0x70e72dc0, aPath=0x6f1812c0, aPattern=..., aOptions=...)
    at /hack/mozilla-central/gfx/2d/DrawTargetSkia.cpp:547
#25 0x67e6f1ca in mozilla::dom::CanvasRenderingContext2D::Fill (this=0x70f5de00, winding=<optimized out>)
    at /hack/mozilla-central/content/canvas/src/CanvasRenderingContext2D.cpp:1699
#26 0x6791651e in mozilla::dom::CanvasRenderingContext2DBinding::fill (cx=0x7034eff0, obj=..., self=0x70f5de00, 
    args=...) at /hack/mozilla-central/obj-mobile-debug/dom/bindings/CanvasRenderingContext2DBinding.cpp:2115
#27 0x679167fe in mozilla::dom::CanvasRenderingContext2DBinding::genericMethod (cx=0x7034eff0, 
    argc=<optimized out>, vp=<optimized out>)


JS callstack:

(gdb) print PrintJSStack()
$2 = 0x6fa5d080 "0 anonymous() [\"http://smashcat.org/av/canvas_test/js/engine.js\":254]\n    this = [object Object]\n1 init() [\"http://smashcat.org/av/canvas_test/\":86]\n    this = [object Window]\n2 onload(event = [object"...

JS code at engine.js:254:

		for(n=0;n<num;n++){
			e=drawList[n];
			s.fillStyle=e[2];
			s.beginPath();
			s.moveTo(e[0][0],e[0][1]);
			for(var i=2;i<e[3];i+=2)
				s.lineTo(e[0][i],e[0][i+1]);
* line 254 *            s.fill();
		}

Notice how the log in logcat is complaining about the OES_standard_derivatives extension.
So, the infolog has this complaint:

  error : Extension GL_OES_standard_derivatives does not support 'require'.

Which seems to refer to this line in the above shader:

  extension GL_OES_standard_derivatives: require
Looks like Skia just assumes this extension exists. We should add a check.
Actually, this reproduces not only in debug builds but also in release. Reproduces immediately in Nightly.
If I understand correctly our own code in GLContextSkia.cpp, this piece of logcat

I/Gecko   (26217): Exported SkiaGL extensions: GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_texture_npot GL_OES_standard_derivatives GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra

means that the GL extensions string claims that OES_standard_derivatives is supported. The infolog seems to complain more specificly about the ':require' statement in the shader.
Oh, indeed. Um in that case I'd say the driver is busted because that is legal GLSL.

Benoit if you can try changing it to 'enable' in GrGLShaderBuilder.cpp that might be interesting.
Also, I see that GrGLCaps.cpp does in fact check for the existence of this extension correctly
What it looks like is that the shader compiler considers OES_standard_derivatives as unsupported, but the GL_EXTENSIONS string still lists it. We can work around that by marking it as unsupported when we initialize the GLContext.
Note: I had to choose between marking the extension as unsupported, or marking the GLFeature as unsupported. I did the latter, because it's generally the right thing to do, and by analogy with what the code above already does for Adrenos. But GLContextSkia uses IsExtensionSupported. I had to change that to using IsSupported(GLFeature). Some day I hope we can consistently switch to testing for features, not testing for extensions, otherwise our MarkUnsupported workarounds marking features as unsupported do not take effect.
Attachment #8358017 - Flags: review?(snorp)
Attachment #8358017 - Flags: review?(jgilbert)
Comment on attachment 8358017 [details] [diff] [review]
Mark standard_derivatives as unsupported on Vivante drivers

Review of attachment 8358017 [details] [diff] [review]:
-----------------------------------------------------------------

In the case here where we are proxying the extension list, IsSupported seems a little less clear compared to IsExtensionSupported, but alright.
Attachment #8358017 - Flags: review?(snorp) → review+
In fact, I agree. The present case is a good example of how it would be useful to keep exposing a IsExtensionSupported method that gives the right answer. Currently we only have a mapping of which extensions are required for each feature. What we are missing here, is the knowledge of which extensions should be disabled when a feature is disabled. There's a basic conceptual problem left to be solved there.
Attachment #8358017 - Flags: review?(jgilbert) → review+
https://hg.mozilla.org/integration/mozilla-inbound/rev/7d5fcd8a3a99
Assignee: nobody → bjacob
Target Milestone: --- → mozilla29
https://hg.mozilla.org/mozilla-central/rev/7d5fcd8a3a99
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: