1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */
7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
9f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#ifndef GrGLProgram_DEFINED
10f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#define GrGLProgram_DEFINED
11f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
126177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com#include "GrGLContext.h"
135d8f69f2d492a15189e4b976ccca3fa092876419egdaniel#include "GrProgramDesc.h"
14890e3b58e78c0825820f75f1f0c5a5d71e855aa6bsalomon@google.com#include "GrGLTexture.h"
157510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen#include "GrGLProgramDataManager.h"
16018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
177ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
18f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
19f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com#include "SkString.h"
2097c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo
21d8dd47b5fa52430a1ab5c07335c0c13fcd43a82djoshualitt#include "builders/GrGLProgramBuilder.h"
22d8dd47b5fa52430a1ab5c07335c0c13fcd43a82djoshualitt
2347bb38283072dc87dc93220cd2f370ca109972ffjoshualittclass GrGLInstalledProcessors;
2430ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLProgramBuilder;
258dd688b7569df569a672a8a67b2db86a9d376cfcegdanielclass GrPipeline;
26f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
27f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com/**
28f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * This class manages a GPU program and records per-program information.
29f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * We can specify the attribute locations so that they are constant
30f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * across our shaders. But the driver determines the uniform locations
31f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * at link time. We don't need to remember the sampler uniform location
32f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * because we will bind a texture slot to it and never change it
33f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * Uniforms are program-local so we can't rely on fHWState to hold the
34f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * previous uniform state after a program change.
35f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */
36a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.orgclass GrGLProgram : public SkRefCnt {
37f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.compublic:
387ea439b2203855db97330b25945b87dd4b170b8begdaniel    typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
39dddc18a6bba67ad43a65f4c244b95f76cefef617kkinnunen
40d8dd47b5fa52430a1ab5c07335c0c13fcd43a82djoshualitt    ~GrGLProgram();
41f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
4234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    /**
4334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Call to abandon GL objects owned by this program.
4434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     */
45ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void abandon();
46ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
4779f8faeea2692d2948c0f634e956d1e7fc8333e0joshualitt    const GrProgramDesc& getDesc() { return fDesc; }
489ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
49271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    /**
506a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com     * Gets the GL program ID for this program.
516a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com     */
52dddc18a6bba67ad43a65f4c244b95f76cefef617kkinnunen    GrGLuint programID() const { return fProgramID; }
536a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com
546a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com    /**
55ee2af95db72152dfa61c841875df0594ca93437djoshualitt     * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
56ee2af95db72152dfa61c841875df0594ca93437djoshualitt     * space and to make device space positions have the correct origin for processors that require
57ee2af95db72152dfa61c841875df0594ca93437djoshualitt     * them.
586a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com     */
59ee2af95db72152dfa61c841875df0594ca93437djoshualitt    struct RenderTargetState {
606a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com        SkISize         fRenderTargetSize;
616a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com        GrSurfaceOrigin fRenderTargetOrigin;
626a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com
63ee2af95db72152dfa61c841875df0594ca93437djoshualitt        RenderTargetState() { this->invalidate(); }
646a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com        void invalidate() {
6545a412ee365694c61b50f6177382b509d1e2462bbsalomon@google.com            fRenderTargetSize.fWidth = -1;
6645a412ee365694c61b50f6177382b509d1e2462bbsalomon@google.com            fRenderTargetSize.fHeight = -1;
676a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
686a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com        }
6947c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org
7047c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org        /**
715af9ea399d5e0344cc4b7da4e97b5dc5b3c74f64Ethan Nicholas         * Gets a float4 that adjusts the position from Skia device coords to GL's normalized device
725af9ea399d5e0344cc4b7da4e97b5dc5b3c74f64Ethan Nicholas         * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is
7347c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org         * applied as such:
7447c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org         * pos.x = dot(v.xy, pos.xz)
75ef4ba3da0b1fe375b9631bcd17c43c645f4aa5a6robertphillips         * pos.y = dot(v.zw, pos.yz)
7647c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org         */
77018fb62d12d1febf121fe265da5b6117b86a6541egdaniel        void getRTAdjustmentVec(float* destVec) {
7847c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org            destVec[0] = 2.f / fRenderTargetSize.fWidth;
7947c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org            destVec[1] = -1.f;
8047c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
8147c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org                destVec[2] = -2.f / fRenderTargetSize.fHeight;
8247c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org                destVec[3] = 1.f;
8347c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org            } else {
8447c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org                destVec[2] = 2.f / fRenderTargetSize.fHeight;
8547c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org                destVec[3] = -1.f;
8647c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org            }
8747c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org        }
886a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com    };
896a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com
906a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com    /**
917dc4bd06fca73a97dcf3ad4a7425597160f1edfcegdaniel     * This function uploads uniforms, calls each GrGL*Processor's setData, and retrieves the
924271765d110be2661562f30f47addc9cb69ca4c7cdalton     * textures that need to be bound on each unit. It is the caller's responsibility to ensure
934271765d110be2661562f30f47addc9cb69ca4c7cdalton     * the program is bound before calling, and to bind the outgoing textures to their respective
944271765d110be2661562f30f47addc9cb69ca4c7cdalton     * units upon return. (Each index in the array corresponds to its matching GL texture unit.)
954285accf5af574e6c826d5d09f0359c6149fd717bsalomon@google.com     */
9674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    void setData(const GrPrimitiveProcessor&, const GrPipeline&);
979196130af83782fcac4334117142475a837dd74dbsalomon@google.com
9833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    /**
9933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman     * This function retrieves the textures that need to be used by each GrGL*Processor, and
10033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman     * ensures that any textures requiring mipmaps have their mipmaps correctly built.
10133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman     */
10233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&);
10333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
10447bb38283072dc87dc93220cd2f370ca109972ffjoshualittprotected:
105f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    using UniformHandle    = GrGLSLProgramDataManager::UniformHandle ;
106f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
107f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
108dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
109861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon    GrGLProgram(GrGLGpu*,
11079f8faeea2692d2948c0f634e956d1e7fc8333e0joshualitt                const GrProgramDesc&,
11147bb38283072dc87dc93220cd2f370ca109972ffjoshualitt                const BuiltinUniformHandles&,
11247bb38283072dc87dc93220cd2f370ca109972ffjoshualitt                GrGLuint programID,
113101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon                const UniformInfoArray& uniforms,
114bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel                const UniformInfoArray& textureSamplers,
115bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel                const UniformInfoArray& texelBuffers,
1160eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                const VaryingInfoArray&, // used for NVPR only currently
117369e8b70eedfd151c7f88e50d7f430f4cda5d57eRobert Phillips                std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
118369e8b70eedfd151c7f88e50d7f430f4cda5d57eRobert Phillips                std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
11909aa1fce69b214714171db12c341aebd78dd29eaegdaniel                const GrGLSLFragProcs& fragmentProcessors);
1202c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com
12174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    // A helper to loop over effects, set the transforms (via subclass) and bind textures
122bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel    void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx,
123559f556d9d70ef9d1202e436a56d48364b279ac6Brian Salomon                         int* nextTexelBufferIdx);
12447bb38283072dc87dc93220cd2f370ca109972ffjoshualitt
1252c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com    // Helper for setData() that sets the view matrix and loads the render target height uniform
126b0e93a22bbfad05bb834e33387880ece56e0f6d2Robert Phillips    void setRenderTargetState(const GrPrimitiveProcessor&, const GrRenderTargetProxy*);
1272c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com
12874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    // Helper for setData() that binds textures and texel buffers to the appropriate texture units
129bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel    void bindTextures(const GrResourceIOProcessor&, bool allowSRGBInputs, int* nextSamplerIdx,
130559f556d9d70ef9d1202e436a56d48364b279ac6Brian Salomon                      int* nextTexelBufferIdx);
13174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
13233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Helper for generateMipmaps() that ensures mipmaps are up to date
133ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon    void generateMipmaps(const GrResourceIOProcessor&, bool allowSRGBInputs);
13433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
13534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    // these reflect the current values of uniforms (GL uniform values travel with program)
136ee2af95db72152dfa61c841875df0594ca93437djoshualitt    RenderTargetState fRenderTargetState;
13747bb38283072dc87dc93220cd2f370ca109972ffjoshualitt    BuiltinUniformHandles fBuiltinUniformHandles;
13847bb38283072dc87dc93220cd2f370ca109972ffjoshualitt    GrGLuint fProgramID;
1396eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
14047bb38283072dc87dc93220cd2f370ca109972ffjoshualitt    // the installed effects
141145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
142145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
143fa8963252e122c5288c8e92b5ecc25a8fea21c3begdaniel    GrGLSLFragProcs fFragmentProcessors;
1449681eebb0e441cee25b6faac82c3728512acda27skia.committer@gmail.com
14579f8faeea2692d2948c0f634e956d1e7fc8333e0joshualitt    GrProgramDesc fDesc;
146861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon    GrGLGpu* fGpu;
14747bb38283072dc87dc93220cd2f370ca109972ffjoshualitt    GrGLProgramDataManager fProgramDataManager;
1486eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
149bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel    int fNumTextureSamplers;
150bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel    int fNumTexelBuffers;
151bc5d4d769098a4fb46685c0e59034dc8e12318a2Greg Daniel
15247bb38283072dc87dc93220cd2f370ca109972ffjoshualitt    friend class GrGLProgramBuilder;
1536b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
154a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    typedef SkRefCnt INHERITED;
155f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com};
156f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
157f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#endif
158