question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Android shader compilation failure [Android 8, Android 9]

See original GitHub issue

Bug reports

[Sat Sep 19 2020 08:41:43.614]  ERROR    [GLError: gl-shader: Error compiling shader:
Compile failed.
ERROR: 0:1: '' :   Invalid directive 14
ERROR: 1 compilation errors. No code generated.

] 

Also Invalid directive changes from 10 to 14 Example code:

//@flow
import React, { PureComponent, Component } from "react";
import { Shaders, Node, GLSL, Bus } from "gl-react";
import { Surface } from "../../gl-react-implementation";
import marioPNG from "../../images/pixeleditor-mario.png";
import respondToTouchPosition from "../../HOC/respondToTouchPosition";

type Vec2 = [number, number];

const shaders = Shaders.create({
  paint: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse;
uniform float brushRadius;
uniform bool drawing;
void main() {
  vec2 p = floor(uv * size) / size;
  if (drawing) {
    vec2 d = uv - mouse;
    if (length(d) < brushRadius) {
      gl_FragColor = color;
    }
    else {
      discard;
    }
  }
  else {
    discard;
  }
}`
  },
  initTexture: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform sampler2D t;
void main(){
  gl_FragColor=texture2D(t,uv);
}`
  },
  pixelEditor: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse, gridBorder;
uniform float brushRadius;
uniform sampler2D t;
void main() {
  vec2 p = floor(uv * size) / size;
  vec2 remain = mod(uv * size, vec2(1.0));
  float m =
    step(remain.x, 1.0 - gridBorder.x) *
    step(remain.y, 1.0 - gridBorder.y);
  float inBrushSize =
    step(length(p + (0.5 / size) - mouse), brushRadius);
  vec4 c = mix(texture2D(t, uv), color, 0.6 * inBrushSize);
  gl_FragColor = vec4(
    m * c.rgb,
    mix(1.0, c.a, m));
}`
  }
});

class Paint extends PureComponent {
  state = {
    initialized: false
  };
  onDraw = () => {
    if (!this.state.initialized) {
      this.setState({ initialized: true });
    }
  };
  render() {
    const { initialTexture, onPaintNodeRef, ...rest } = this.props;
    const { initialized } = this.state;
    return (
      <Node
        ref={onPaintNodeRef}
        sync={!initialized}
        shader={!initialized ? shaders.initTexture : shaders.paint}
        width={rest.size[0]}
        height={rest.size[1]}
        uniforms={!initialized ? { t: initialTexture } : rest}
        clear={null}
        onDraw={this.onDraw}
      />
    );
  }
}

class PixelEditor extends PureComponent {
  render() {
    const { gridBorder, ...rest } = this.props;
    const { size, brushRadius, mouse, color } = rest;
    return (
      <Node
        shader={shaders.pixelEditor}
        uniformsOptions={{
          t: { interpolation: "nearest" }
        }}
        uniforms={{
          size,
          gridBorder,
          brushRadius,
          mouse,
          color
        }}
      >
        <Bus uniform="t">
          <Paint {...rest} />
        </Bus>
      </Node>
    );
  }
}

const size = [16, 16];
const gridBorder = [1 / 8, 1 / 8];
const tools = {
  "brush-1": { brushRadius: 0.55 / 16 },
  "brush-2": { brushRadius: 1.1 / 16 },
  "brush-4": { brushRadius: 2.2 / 16 },
  rubber: { brushRadius: 4 / 16, forceColor: [0, 0, 0, 0] },
  "color-picker": { colorPick: true }
};

const Example = respondToTouchPosition(
  class extends Component {
    render() {
      const { color, toolKey, touching, touchPosition, width } = this.props;
      const tool = tools[toolKey];
      return (
        <Surface
          style={{ width, height: width }}
          preload={[marioPNG]}
          webglContextAttributes={{ preserveDrawingBuffer: true }}
        >
          <PixelEditor
            gridBorder={gridBorder}
            initialTexture={marioPNG}
            drawing={touching}
            color={tool.forceColor || color}
            mouse={[touchPosition.x, touchPosition.y]}
            brushRadius={tool.brushRadius || 0}
            size={size}
            onPaintNodeRef={this.onPaintNodeRef}
          />
        </Surface>
      );
    }

    onColorChange = rgb => {
      this.props.setToolState({ color: rgb.concat([1]) });
    };

    paintNode: Node;
    onPaintNodeRef = (ref: Node) => {
      this.paintNode = ref;
    };

    colorPick = ([x, y]: Vec2) => {
      x = Math.floor(x * size[0]);
      y = Math.floor(y * size[1]);
      const ndarray = this.paintNode.capture(x, y, 1, 1);
      this.props.setToolState({
        color: Array.from(ndarray.data).map(n => n / 255)
      });
    };
  }
);

Example.defaultProps = {
  color: [1, 1, 1, 1],
  toolKey: "brush-4"
};

export default Example;

export { tools };

(Example is pixel editor from cookbook)

library version

Unimodules with expo is used on top of bare React Native

├── gl-react@4.0.1 
└─┬ gl-react-native@4.0.1 
  └── gl-react-expo@4.0.1 

Expected behavior

  1. Shaders successfully compiled

Actual behavior

  1. On certain mobile phones shaders are not compiled and causing a crash

NB!: Seems like GLImage from gl-react-image actually works correctly

Steps to reproduce the behavior

  1. Open the screen with Pixel Editor

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Shamash2014commented, Dec 24, 2020

And than basically shader is executed on the Node. I haven’t found any significant performance problem with this approach as well 😃

0reactions
Shamash2014commented, Dec 24, 2020

@gre Let me give you an example of the code which worked for me.

This one won`t work on certain phones.

const shaders = Shaders.create({
  paint: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse;
uniform float brushRadius;
uniform bool drawing;
void main() {
  vec2 p = floor(uv * size) / size;
  if (drawing) {
    vec2 d = uv - mouse;
    if (length(d) < brushRadius) {
      gl_FragColor = color;
    }
    else {
      discard;
    }
  }
  else {
    discard;
  }
}`
  },
  initTexture: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform sampler2D t;
void main(){
  gl_FragColor=texture2D(t,uv);
}`
  },
  pixelEditor: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse, gridBorder;
uniform float brushRadius;
uniform sampler2D t;
void main() {
  vec2 p = floor(uv * size) / size;
  vec2 remain = mod(uv * size, vec2(1.0));
  float m =
    step(remain.x, 1.0 - gridBorder.x) *
    step(remain.y, 1.0 - gridBorder.y);
  float inBrushSize =
    step(length(p + (0.5 / size) - mouse), brushRadius);
  vec4 c = mix(texture2D(t, uv), color, 0.6 * inBrushSize);
  gl_FragColor = vec4(
    m * c.rgb,
    mix(1.0, c.a, m));
}`
  }
});

This one is actually working fine, even on android 7 or some low tier tablets

const shaders = {
  paint: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse;
uniform float brushRadius;
uniform bool drawing;
void main() {
  vec2 p = floor(uv * size) / size;
  if (drawing) {
    vec2 d = uv - mouse;
    if (length(d) < brushRadius) {
      gl_FragColor = color;
    }
    else {
      discard;
    }
  }
  else {
    discard;
  }
}`
  },
  initTexture: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform sampler2D t;
void main(){
  gl_FragColor=texture2D(t,uv);
}`
  },
  pixelEditor: {
    frag: GLSL`
precision highp float;
varying vec2 uv;
uniform vec4 color;
uniform vec2 size, mouse, gridBorder;
uniform float brushRadius;
uniform sampler2D t;
void main() {
  vec2 p = floor(uv * size) / size;
  vec2 remain = mod(uv * size, vec2(1.0));
  float m =
    step(remain.x, 1.0 - gridBorder.x) *
    step(remain.y, 1.0 - gridBorder.y);
  float inBrushSize =
    step(length(p + (0.5 / size) - mouse), brushRadius);
  vec4 c = mix(texture2D(t, uv), color, 0.6 * inBrushSize);
  gl_FragColor = vec4(
    m * c.rgb,
    mix(1.0, c.a, m));
}`
  }
};
Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Android shader compilation failure [Android 8, Android 9]
Coming soon: A brand new website interface for an even better experience!
Read more >
Flutter 1.9: D/skia ( 5106): Shader compilation error
4 application using Android Studio 3.5.1. After adding successfully a new virtual device (Nexus 6) and tried to run my app, I got...
Read more >
1507074 - Shader compilation failed when ... - Bugzilla@Mozilla
This bug is created by Bug 1499255 Comment 8. Shader compilation failed when GL_OES_EGL_image_external_essl3 is not supported on android device.
Read more >
Android : Flutter 1.9: D/skia ( 5106): Shader compilation error
Android : Flutter 1.9: D/skia ( 5106): Shader compilation error [ Beautify Your Computer : https://www.hows.tech/p/recommended.html ] ...
Read more >
Crashes - Android Developers
Per-device bad behavior threshold: At least 8% of daily active users ... Kotlin does not create compile time errors but these references can ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found