1086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com/*
2086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com * Copyright 2011 Google Inc.
3086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com *
4086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
5086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com * found in the LICENSE file.
6086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com */
7086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com
8086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com#include "GrGLSL.h"
9e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com#include "GrGLShaderVar.h"
104af0af612f8cfb6951feb10ffe3091821866bd44bsalomon@google.com#include "SkString.h"
11086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com
12f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.orgbool GrGetGLSLGeneration(const GrGLInterface* gl, GrGLSLGeneration* generation) {
13f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org    SkASSERT(NULL != generation);
14086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com    GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
15f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org    if (GR_GLSL_INVALID_VER == ver) {
16f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org        return false;
17f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org    }
189e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org    switch (gl->fStandard) {
199e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org        case kGL_GrGLStandard:
20f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(ver >= GR_GLSL_VER(1,10));
21086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com            if (ver >= GR_GLSL_VER(1,50)) {
22f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org                *generation = k150_GrGLSLGeneration;
23281c726c760c2b0ef957674da0360d5595d52a9cbsalomon@google.com            } else if (ver >= GR_GLSL_VER(1,40)) {
24f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org                *generation = k140_GrGLSLGeneration;
25086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com            } else if (ver >= GR_GLSL_VER(1,30)) {
26f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org                *generation = k130_GrGLSLGeneration;
27086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com            } else {
28f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org                *generation = k110_GrGLSLGeneration;
29086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com            }
30f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org            return true;
319e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org        case kGLES_GrGLStandard:
32086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com            // version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
33f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(ver >= GR_GL_VER(1,00));
34f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org            *generation = k110_GrGLSLGeneration;
35f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org            return true;
36086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com        default:
3788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unknown GL Standard");
38f4e67e3e5e5017284300a61e7bb046723a44b0cfcommit-bot@chromium.org            return false;
39086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com    }
40086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com}
41086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com
4206f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.orgconst char* GrGetGLSLVersionDecl(const GrGLContextInfo& info) {
4306f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org    switch (info.glslGeneration()) {
44e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com        case k110_GrGLSLGeneration:
459e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org            if (kGLES_GrGLStandard == info.standard()) {
46e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com                // ES2s shader language is based on version 1.20 but is version
47e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com                // 1.00 of the ES language.
48e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com                return "#version 100\n";
49e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com            } else {
509e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org                SkASSERT(kGL_GrGLStandard == info.standard());
51e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com                return "#version 110\n";
52e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com            }
53e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com        case k130_GrGLSLGeneration:
549e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org            SkASSERT(kGL_GrGLStandard == info.standard());
55e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com            return "#version 130\n";
56281c726c760c2b0ef957674da0360d5595d52a9cbsalomon@google.com        case k140_GrGLSLGeneration:
579e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org            SkASSERT(kGL_GrGLStandard == info.standard());
58281c726c760c2b0ef957674da0360d5595d52a9cbsalomon@google.com            return "#version 140\n";
59e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com        case k150_GrGLSLGeneration:
609e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org            SkASSERT(kGL_GrGLStandard == info.standard());
6106f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org            if (info.caps()->isCoreProfile()) {
6206f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org                return "#version 150\n";
6306f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org            } else {
6406f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org                return "#version 150 compatibility\n";
6506f05989570fbf2ced3d2d1690ea1276b7330b5fcommit-bot@chromium.org            }
66e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com        default:
6788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unknown GL version.");
68e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com            return ""; // suppress warning
69e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com    }
70e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com}
71e55fd0f188a2b0b137ddfd9728da58481e2309efbsalomon@google.com
72868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.comnamespace {
73018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com    void append_tabs(SkString* outAppend, int tabCnt) {
74018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com        static const char kTabs[] = "\t\t\t\t\t\t\t\t";
75018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com        while (tabCnt) {
76972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org            int cnt = SkTMin((int)SK_ARRAY_COUNT(kTabs), tabCnt);
77018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com            outAppend->append(kTabs, cnt);
78018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com            tabCnt -= cnt;
79018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com        }
80868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    }
81868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com}
82868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
83824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.orgvoid GrGLSLMulVarBy4f(SkString* outAppend,
84824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org                      unsigned tabCnt,
85824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org                      const char* vec4VarName,
86a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                      const GrGLSLExpr4& mulFactor) {
87824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org    if (mulFactor.isOnes()) {
88824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org        *outAppend = SkString();
89868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    }
90824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org
91868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    append_tabs(outAppend, tabCnt);
92868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
93824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org    if (mulFactor.isZeros()) {
94824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org        outAppend->appendf("%s = vec4(0);\n", vec4VarName);
958660783e196dc3cb4ead492253a493844fa43f7acommit-bot@chromium.org    } else {
968660783e196dc3cb4ead492253a493844fa43f7acommit-bot@chromium.org        outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor.c_str());
974af0af612f8cfb6951feb10ffe3091821866bd44bsalomon@google.com    }
984af0af612f8cfb6951feb10ffe3091821866bd44bsalomon@google.com}
99