1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef PROGRAM_DATA_H
17 #define PROGRAM_DATA_H
18 
19 #include "ShaderParser.h"
20 
21 #include "aemu/base/containers/HybridComponentManager.h"
22 
23 #include <memory>
24 #include <sstream>
25 #include <string>
26 #include <unordered_map>
27 
28 struct GLUniformDesc {
29     GLUniformDesc() = default;
30     GLUniformDesc(const char* name, GLint location, GLsizei count, GLboolean transpose,
31             GLenum type, GLsizei size, unsigned char* val);
32     GLUniformDesc(android::base::Stream* stream);
33     GLUniformDesc(GLUniformDesc&&) = default;
34     GLUniformDesc& operator=(GLUniformDesc&&) = default;
35 
36     GLsizei mCount = 0;
37     GLboolean mTranspose = GL_FALSE;
38     GLenum mType = (GLenum)0;
39     std::vector<unsigned char> mVal;
40 
41     std::string mGuestName = {};
42 
43     void onSave(android::base::Stream* stream) const;
44 };
45 
46 struct AttachedShader {
47     GLuint localName = 0;
48     ShaderParser* shader = nullptr;
49     // linkedSource is only updated when glLinkProgram
50     // This is the "real" source the hardware is using for the compiled program.
51     std::string linkedSource = {};
52 #ifdef USE_ANGLE_SHADER_PARSER
53     ANGLEShaderParser::ShaderLinkInfo linkInfo = {};
54 #endif
55 };
56 
57 class ProgramData : public ObjectData {
58 public:
59     enum ShaderType {
60         VERTEX = 0,
61         FRAGMENT,
62         COMPUTE,
63         NUM_SHADER_TYPE
64     };
65     ProgramData(int glesMaj, int glesMin);
66     ProgramData(android::base::Stream* stream);
67     virtual void onSave(android::base::Stream* stream, unsigned int globalName) const override;
68     virtual void postLoad(const getObjDataPtr_t& getObjDataPtr) override;
69     // restore() in ProgramData must be executed after shaders
70     virtual void restore(ObjectLocalName localName,
71            const getGlobalName_t& getGlobalName) override;
72 
73     GLuint getAttachedVertexShader() const;
74     GLuint getAttachedFragmentShader() const;
75     GLuint getAttachedComputeShader() const;
76     GLuint getAttachedShader(GLenum type) const;
77 
78     std::string getTranslatedName(const std::string& userVarName) const;
79     std::string getDetranslatedName(const std::string& driverName) const;
80 
81     bool attachShader(GLuint shader, ShaderParser* shaderData, GLenum type);
82     bool isAttached(GLuint shader) const;
83     bool detachShader(GLuint shader);
84     void bindAttribLocation(const std::string& var, GLuint loc);
85     void linkedAttribLocation(const std::string& var, GLuint loc);
86 
87     void appendValidationErrMsg(std::ostringstream& ss);
88     bool validateLink(ShaderParser* frag, ShaderParser* vert);
89 
getValidateStatus()90     bool getValidateStatus() const { return ValidateStatus; }
setValidateStatus(bool status)91     void setValidateStatus(bool status) { ValidateStatus = status; }
92 
93     // setLinkStatus resets uniform location virtualization as well
94     void setHostLinkStatus(GLint status);
95     void setLinkStatus(GLint status);
96     bool getLinkStatus() const;
97 
98     void setErrInfoLog();
99 
100     // make sure this is never called with a 0-length log returned from
101     // glGetProgramLog; it can be garbage without a null terminator.
102     void setInfoLog(const GLchar *log);
103     const GLchar* getInfoLog() const;
104 
isInUse()105     bool isInUse() const { return IsInUse; }
setInUse(bool inUse)106     void setInUse(bool inUse) { IsInUse = inUse; }
107 
getDeleteStatus()108     bool getDeleteStatus() const { return DeleteStatus; }
setDeleteStatus(bool status)109     void setDeleteStatus(bool status) { DeleteStatus = status; }
110 
111     // boundAttribLocs stores the attribute locations assigned by
112     // glBindAttribLocation.
113     // It will take effect after glLinkProgram.
114     std::unordered_map<std::string, GLuint> boundAttribLocs;
115     virtual GenNameInfo getGenNameInfo() const override;
addProgramName(GLuint name)116     void addProgramName(GLuint name) { ProgramName = name; }
getProgramName()117     GLuint getProgramName() const { return ProgramName; }
118 
119     // Virtualize uniform locations
120     // It handles location -1 as well
121     void initGuestUniformLocForKey(const std::string& key);
122     void initGuestUniformLocForKey(const std::string& key,
123                                    const std::string& key2);
124     int getGuestUniformLocation(const char* uniName);
125     int getHostUniformLocation(int guestLocation);
126 
127 private:
128     // linkedAttribLocs stores the attribute locations the guest might
129     // know about. It includes all boundAttribLocs before the previous
130     // glLinkProgram and all attribute locations retrieved by glGetAttribLocation
131     std::unordered_map<std::string, GLuint> linkedAttribLocs;
132     std::unordered_map<GLuint, GLUniformDesc> uniforms;
133     AttachedShader attachedShaders[NUM_SHADER_TYPE] = {};
134     std::string validationInfoLog;
135     std::string infoLog;
136     bool ValidateStatus;
137     bool LinkStatus;
138     bool HostLinkStatus;
139     bool IsInUse;
140     bool DeleteStatus;
141     GLuint  ProgramName;
142     std::unordered_map<GLuint, GLuint> mUniformBlockBinding;
143     std::vector<std::string> mTransformFeedbacks;
144     GLenum mTransformFeedbackBufferMode = 0;
145 
146     int mGlesMajorVersion = 2;
147     int mGlesMinorVersion = 0;
148     std::unordered_map<GLuint, GLUniformDesc> collectUniformInfo() const;
149     void getUniformValue(const GLchar *name, GLenum type,
150             std::unordered_map<GLuint, GLUniformDesc> &uniformsOnSave) const;
151 
152     std::unordered_map<std::string, int> mUniNameToGuestLoc;
153     android::base::HybridComponentManager<10000, int, int> mGuestLocToHostLoc;
154 
155     int mCurrUniformBaseLoc = 0;
156     bool mUseUniformLocationVirtualization = true;
157     bool mUseDirectDriverUniformInfo = false;
158 };
159 #endif
160