Skip to content

Skia shader cause a compilation error #487

@afxgroup

Description

@afxgroup

I'm trying to use Skia library with GL4ES. If shaders are not involved everything seems to work while once a shader is involved an compilation error occur. This is the shader created by GL4ES:

#version 110
#extension GL_EXT_shader_non_constant_global_initializers : enable
precision highp float;
float dFdx(float p) {return 0.0001;}
vec2 dFdx(vec2 p) {return vec2(0.0001);}
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 dFdx(vec3 p) {return vec3(0.0001);}
float dFdy(float p) {return 0.0001;}
vec2 dFdy(vec2 p) {return vec2(0.0001);}
vec3 dFdy(vec3 p) {return vec3(0.0001);}
float fwidth(float p) {return abs(dFdx(p))+abs(dFdy(p));}
vec2 fwidth(vec2 p) {return abs(dFdx(p))+abs(dFdy(p));}
vec3 fwidth(vec3 p) {return abs(dFdx(p))+abs(dFdy(p));}
#define GL4ES
precision highp int;


varying vec4 vcolor_S0;
varying vec2 varccoord_S0;
void main() {
	vec4 outputColor_S0 = vcolor_S0;
	float x_plus_1 = varccoord_S0.x;
	float y = varccoord_S0.y;
	float coverage;
	if (0.00000 == x_plus_1) {
		coverage = y;
	} else {
		float fn = x_plus_1 * (x_plus_1 - 2.00000);
		fn = ((y) * (y) + (fn));
		float fnwidth = fwidth(fn);
		coverage = 0.500000 - fn / fnwidth;
		coverage = clamp(coverage, 0.00000, 1.00000);
	}
	coverage = float(coverage >= 0.500000);
	vec4 outputCoverage_S0 = vec4(coverage);
	{
		gl_FragColor = outputColor_S0 * outputCoverage_S0;
	}
}

You can try it here:

https://shader-playground.timjones.io/82f451461cb682120eece7c3aa6094f7

This is the code i'm using as test:

#include "GLFW/glfw3.h"
#define SK_GANESH
#define SK_GL
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/gl/GrGLDirectContext.h"
#include "include/gpu/ganesh/gl/GrGLInterface.h"
#include "include/gpu/ganesh/gl/GrGLAssembleInterface.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkSurface.h"
#include "include/core/SkFont.h"

#include <stdio.h>
#include <stdlib.h>

//uncomment the two lines below to enable correct color spaces
//#define GL_FRAMEBUFFER_SRGB 0x8DB9
//#define GL_SRGB8_ALPHA8 0x8C43

GrDirectContext* sContext = nullptr;
SkSurface* sSurface = nullptr;

void error_callback(int error, const char* description) {
        fputs(description, stderr);
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
                glfwSetWindowShouldClose(window, GL_TRUE);
}

void init_skia(int w, int h) {
        auto interface = GrGLMakeNativeInterface();
        if (interface == nullptr) {
                //backup plan. see https://gist.github.com/ad8e/dd150b775ae6aa4d5cf1a092e4713add?permalink_comment_id=4680136#gistcomment-4680136
                interface = GrGLMakeAssembledInterface(
                        nullptr, (GrGLGetProc) * [](void*, const char* p) -> void* { return (void*)glfwGetProcAddress(p); });
        }
        sContext = GrDirectContexts::MakeGL(interface).release();

        GrGLFramebufferInfo framebufferInfo;
        framebufferInfo.fFBOID = 0; // assume default framebuffer
        // We are always using OpenGL and we use RGBA8 internal format for both RGBA and BGRA configs in OpenGL.
        //(replace line below with this one to enable correct color spaces) framebufferInfo.fFormat = GL_SRGB8_ALPHA8;
        framebufferInfo.fFormat = GL_RGBA8;

        SkColorType colorType = kRGBA_8888_SkColorType;
        GrBackendRenderTarget backendRenderTarget = GrBackendRenderTargets::MakeGL(w, h,
                0, // sample count
                0, // stencil bits
                framebufferInfo);

        //(replace line below with this one to enable correct color spaces) sSurface = SkSurfaces::WrapBackendRenderTarget(sContext, backendRenderTarget>
        sSurface = SkSurfaces::WrapBackendRenderTarget(sContext, backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, nullptr).release(>
        if (sSurface == nullptr) abort();
}

void cleanup_skia() {
        delete sSurface;
        delete sContext;
}

const int kWidth = 960;
const int kHeight = 640;

int main(void) {
        GLFWwindow* window;
        glfwSetErrorCallback(error_callback);
        if (!glfwInit()) {
                exit(EXIT_FAILURE);
        }

        //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
        //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        //(uncomment to enable correct color spaces) glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
        glfwWindowHint(GLFW_STENCIL_BITS, 0);
        //glfwWindowHint(GLFW_ALPHA_BITS, 0);
        glfwWindowHint(GLFW_DEPTH_BITS, 0);

        window = glfwCreateWindow(kWidth, kHeight, "Simple example", NULL, NULL);
        if (!window) {
                glfwTerminate();
                exit(EXIT_FAILURE);
        }
        glfwMakeContextCurrent(window);
        //(uncomment to enable correct color spaces) glEnable(GL_FRAMEBUFFER_SRGB);

        init_skia(kWidth, kHeight);

        glfwSwapInterval(1);
        glfwSetKeyCallback(window, key_callback);
        // Draw to the surface via its SkCanvas.
        SkCanvas* canvas = sSurface->getCanvas(); // We don't manage this pointer's lifetime.
        SkFont font; 
        font.setSize(24);

        while (!glfwWindowShouldClose(window)) {
                glfwWaitEvents();
                SkPaint paint;
                paint.setColor(SK_ColorWHITE);
                canvas->drawPaint(paint);
                paint.setColor(SK_ColorBLUE);
                canvas->drawRect({100, 200, 300, 500}, paint);
                canvas->drawCircle(100, 100, 64, paint);
                canvas->drawString("Hello AmigaOS4! We are working hard!", 10, 20, font, paint);
                sContext->flush();

                glfwSwapBuffers(window);
        }

        cleanup_skia();

        glfwDestroyWindow(window);
        glfwTerminate();
        exit(EXIT_SUCCESS);
}

If you comment the drawString you will not have any error

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions