1168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com/*
2168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * Copyright 2012 Google Inc.
3168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com *
4168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
5168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * found in the LICENSE file.
6168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com */
7168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com
8b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#ifndef GrGLProcessor_DEFINED
9b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#define GrGLProcessor_DEFINED
10168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com
11b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrBackendProcessorFactory.h"
123390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org#include "GrGLProgramEffects.h"
13168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com#include "GrGLShaderVar.h"
14168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com#include "GrGLSL.h"
15168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com
16168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com/** @file
17374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com    This file contains specializations for OpenGL of the shader stages declared in
18b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    include/gpu/GrProcessor.h. Objects of type GrGLProcessor are responsible for emitting the
19b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLSL code that implements a GrProcessor and for uploading uniforms at draw time. If they don't
2077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    always emit the same GLSL code, they must have a function:
21b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*)
22b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    that is used to implement a program cache. When two GrProcessors produce the same key this means
23b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    that their GrGLProcessors would emit the same GLSL code.
24374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com
25b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    The GrGLProcessor subclass must also have a constructor of the form:
26b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrProcessor&)
27c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
28b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    These objects are created by the factory object returned by the GrProcessor::getFactory().
29168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com*/
30168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com
31b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLProcessor {
32168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.compublic:
33b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrGLProcessor(const GrBackendProcessorFactory& factory)
34b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        : fFactory(factory) {
35b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    }
36b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
3723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
3823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
3923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    /**
40b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * Passed to GrGLProcessors so they can add transformed coordinates to their shader code.
4123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt     */
4223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    typedef GrShaderVar TransformedCoords;
4323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    typedef SkTArray<GrShaderVar> TransformedCoordsArray;
4423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
4523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    /**
46b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * Passed to GrGLProcessors so they can add texture reads to their shader code.
4723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt     */
4823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    class TextureSampler {
4923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    public:
5023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
5123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt            : fSamplerUniform(uniform)
5223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt            , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
5323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt            SkASSERT(0 != fConfigComponentMask);
5423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt            memcpy(fSwizzle, access.getSwizzle(), 5);
5523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        }
5623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
5723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        // bitfield of GrColorComponentFlags present in the texture's config.
5823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        uint32_t configComponentMask() const { return fConfigComponentMask; }
5923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        // this is .abcd
6023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        const char* swizzle() const { return fSwizzle; }
6123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
6223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    private:
6323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        UniformHandle fSamplerUniform;
6423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        uint32_t      fConfigComponentMask;
6523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        char          fSwizzle[5];
6623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
6723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        friend class GrGLShaderBuilder;
6823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    };
6923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
7023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    typedef SkTArray<TextureSampler> TextureSamplerArray;
712eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com
72b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual ~GrGLProcessor() {}
73b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
74b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    /** A GrGLProcessor instance can be reused with any GrProcessor that produces the same stage
75b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        key; this function reads data from a GrProcessor and uploads any uniform variables required
76b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        by the shaders created in emitCode(). The GrProcessor installed in the GrDrawEffect is
77b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        guaranteed to be of the same type that created this GrGLProcessor and to have an identical
78b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        effect key as the one that created this GrGLProcessor. Effects that use local coords have
79b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        to consider whether the GrProcessorStage's coord change matrix should be used. When explicit
80b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        local coordinates are used it can be ignored. */
81b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) {}
82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
83b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const char* name() const { return fFactory.name(); }
84b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
85b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
86b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
87b0a8a377f832c59cee939ad721e1f87d378b7142joshualittprotected:
88b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const GrBackendProcessorFactory& fFactory;
89b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt};
90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
91b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLFragmentProcessor : public GrGLProcessor {
92b0a8a377f832c59cee939ad721e1f87d378b7142joshualittpublic:
93b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrGLFragmentProcessor(const GrBackendProcessorFactory& factory)
94b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        : INHERITED(factory) {
95261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
96f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
97b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual ~GrGLFragmentProcessor() {}
98d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com
99374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com    /** Called when the program stage should insert its code into the shaders. The code in each
100374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com        shader will be in its own block ({}) and so locally scoped names will not collide across
101374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com        stages.
102374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com
103374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com        @param builder      Interface used to emit code in the shaders.
10449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        @param effect       The effect that generated this program stage.
105b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        @param key          The key that was computed by GenKey() from the generating GrProcessor.
106374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com        @param outputColor  A predefined vec4 in the FS in which the stage should place its output
107374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                            color (or coverage).
108374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com        @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
109374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                            NULL in which case the implied input is solid white (all ones).
110374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                            TODO: Better system for communicating optimization info (e.g. input
111374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                            color is solid white, trans black, known to be opaque, etc.) that allows
112f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com                            the effect to communicate back similar known info about its output.
113b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        @param samplers     Contains one entry for each GrTextureAccess of the GrProcessor. These
114b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                            can be passed to the builder to emit texture reads in the generated
115b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                            code.
116d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        */
11730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder* builder,
118b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor& effect,
119b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey& key,
120374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                          const char* outputColor,
121374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                          const char* inputColor,
12277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                          const TransformedCoordsArray& coords,
123374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com                          const TextureSamplerArray& samplers) = 0;
124374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com
125261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprivate:
126b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLProcessor INHERITED;
127168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com};
128168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com
129168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com#endif
130