1c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com/*
2c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com * Copyright 2012 Google Inc.
3c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com *
4c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
5c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com * found in the LICENSE file.
6c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com */
7c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
8ca5e87e973b87209b5ffa298b8bc6ce0c512a204bsalomon@google.com#ifndef GrGLEffect_DEFINED
9ca5e87e973b87209b5ffa298b8bc6ce0c512a204bsalomon@google.com#define GrGLEffect_DEFINED
10c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
118780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com#include "GrBackendEffectFactory.h"
12eb1f13640c7f2d770a145a9568cd1483aaba4e0etomhudson@google.com#include "GrGLShaderBuilder.h"
13c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com#include "GrGLShaderVar.h"
14c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com#include "GrGLSL.h"
15c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
16b6b7f6d275d9f518b9d84c265c0e50a801458a23tomhudson@google.comclass GrGLTexture;
17c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
18c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com/** @file
1916d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com    This file contains specializations for OpenGL of the shader stages declared in
20aab3f0a5176fa13f1f0452386651dc5c8676ba68bsalomon@google.com    include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
213829e11b4220c9dd4b23985111deefa061716435bsalomon@google.com    GLSL code that implements a GrEffect and for uploading uniforms at draw time. They also
2216d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com    must have a function:
238bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
2401930d4fb6c68c3a2b50922f0bc49032535f5740bsalomon@google.com    that is used to implement a program cache. When two GrEffects produce the same key this means
25ca5e87e973b87209b5ffa298b8bc6ce0c512a204bsalomon@google.com    that their GrGLEffects would emit the same GLSL code.
2616d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com
278bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    The GrGLEffect subclass must also have a constructor of the form:
288bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrDrawEffect&)
298bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    The effect held by the GrDrawEffect is guaranteed to be of the type that generated the
308bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    GrGLEffect subclass instance.
318bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com
323829e11b4220c9dd4b23985111deefa061716435bsalomon@google.com    These objects are created by the factory object returned by the GrEffect::getFactory().
33c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com*/
34c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
358bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.comclass GrDrawEffect;
368bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com
37aab3f0a5176fa13f1f0452386651dc5c8676ba68bsalomon@google.comclass GrGLEffect {
38c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
39c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.compublic:
408780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com    typedef GrBackendEffectFactory::EffectKey EffectKey;
418780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com
42ffd9ba72809740cef9d8457a88a946eae3bbb7bdbsalomon@google.com    enum {
438f0339887c862ab42e1c8ecc7c9085183fd2953cbsalomon@google.com        kNoEffectKey = GrBackendEffectFactory::kNoEffectKey,
449ae086cba571945957b4ea066bf0699862e5ece3bsalomon@google.com        // the number of bits in EffectKey available to GenKey
459ae086cba571945957b4ea066bf0699862e5ece3bsalomon@google.com        kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
46ffd9ba72809740cef9d8457a88a946eae3bbb7bdbsalomon@google.com    };
47ffd9ba72809740cef9d8457a88a946eae3bbb7bdbsalomon@google.com
48f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com    typedef GrGLShaderBuilder::TextureSamplerArray TextureSamplerArray;
49f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com
501f64de790a624dc250d3da0789b3ada6251facb7bsalomon@google.com    GrGLEffect(const GrBackendEffectFactory&);
5128421382a320110785b5f5c389192cfb408b4b7dbsalomon@google.com
52aab3f0a5176fa13f1f0452386651dc5c8676ba68bsalomon@google.com    virtual ~GrGLEffect();
53b6b7f6d275d9f518b9d84c265c0e50a801458a23tomhudson@google.com
5416d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com    /** Called when the program stage should insert its code into the shaders. The code in each
5516d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com        shader will be in its own block ({}) and so locally scoped names will not collide across
5616d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com        stages.
5716d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com
5816d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com        @param builder      Interface used to emit code in the shaders.
598bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        @param drawEffect   A wrapper on the effect that generated this program stage.
60d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com        @param key          The key that was computed by GenKey() from the generating GrEffect.
61d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com                            Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
62d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com                            guaranteed to match the value produced by GenKey();
6316d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com        @param outputColor  A predefined vec4 in the FS in which the stage should place its output
6416d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                            color (or coverage).
6516d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com        @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
6616d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                            NULL in which case the implied input is solid white (all ones).
6716d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                            TODO: Better system for communicating optimization info (e.g. input
6816d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                            color is solid white, trans black, known to be opaque, etc.) that allows
697e0b48a766909be86a2923d909b85c111de4d237bsalomon@google.com                            the effect to communicate back similar known info about its output.
703829e11b4220c9dd4b23985111deefa061716435bsalomon@google.com        @param samplers     One entry for each GrTextureAccess of the GrEffect that generated the
71aab3f0a5176fa13f1f0452386651dc5c8676ba68bsalomon@google.com                            GrGLEffect. These can be passed to the builder to emit texture
7216d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                            reads in the generated code.
7378ab92aa5c32b094205df9565e492d56ddce13cbbsalomon@google.com        */
7416d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com    virtual void emitCode(GrGLShaderBuilder* builder,
758bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com                          const GrDrawEffect& drawEffect,
769ae086cba571945957b4ea066bf0699862e5ece3bsalomon@google.com                          EffectKey key,
7716d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                          const char* outputColor,
7816d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                          const char* inputColor,
7916d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com                          const TextureSamplerArray& samplers) = 0;
8016d2ef4cfb3ded1a3424a372b37c641845095ff3bsalomon@google.com
81aab3f0a5176fa13f1f0452386651dc5c8676ba68bsalomon@google.com    /** A GrGLEffect instance can be reused with any GrEffect that produces the same stage
823829e11b4220c9dd4b23985111deefa061716435bsalomon@google.com        key; this function reads data from a stage and uploads any uniform variables required
838780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com        by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
848780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com        guaranteed to be of the same type that created this GrGLEffect and to have an identical
858bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        EffectKey as the one that created this GrGLEffect. Effects that use local coords have
868bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        to consider whether the GrEffectStage's coord change matrix should be used. When explicit
878bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        local coordinates are used it can be ignored. */
888bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&);
89c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
9028421382a320110785b5f5c389192cfb408b4b7dbsalomon@google.com    const char* name() const { return fFactory.name(); }
9128421382a320110785b5f5c389192cfb408b4b7dbsalomon@google.com
928bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
938bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    static EffectKey GenAttribKey(const GrDrawEffect& stage);
94069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com
953faee6c17c2b30f7418b86c000a1420be2023600tomhudson@google.comprotected:
961f64de790a624dc250d3da0789b3ada6251facb7bsalomon@google.com    const GrBackendEffectFactory& fFactory;
97c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com};
98c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com
99c300f4903ce7ac29d9c8fd119524e4967bab05e1tomhudson@google.com#endif
100