| /* |
| * Copyright 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef GLES_CONTEXT_H |
| #define GLES_CONTEXT_H |
| |
| #include "aemu/base/containers/Lookup.h" |
| #include "aemu/base/files/Stream.h" |
| #include "aemu/base/synchronization/Lock.h" |
| |
| #include "GLDispatch.h" |
| #include "GLESpointer.h" |
| #include "ObjectNameSpace.h" |
| #include "ShareGroup.h" |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| #include <functional> |
| |
| static constexpr int kMaxVertexAttributes = 16; |
| |
| typedef std::unordered_map<GLenum,GLESpointer*> ArraysMap; |
| |
| enum TextureTarget { |
| TEXTURE_2D, |
| TEXTURE_CUBE_MAP, |
| TEXTURE_2D_ARRAY, |
| TEXTURE_3D, |
| TEXTURE_2D_MULTISAMPLE, |
| TEXTURE_BUFFER, |
| NUM_TEXTURE_TARGETS |
| }; |
| |
| typedef struct _textureTargetState { |
| GLuint texture; |
| GLboolean enabled; |
| } textureTargetState; |
| |
| typedef textureTargetState textureUnitState[NUM_TEXTURE_TARGETS]; |
| |
| class Version{ |
| public: |
| explicit Version(int major = 0,int minor = 0,int release = 0); |
| Version(const char* versionString); |
| Version(const Version& ver); |
| bool operator<(const Version& ver) const; |
| Version& operator=(const Version& ver); |
| private: |
| int m_major; |
| int m_minor; |
| int m_release; |
| }; |
| |
| struct GLSupport { |
| int maxLights = 0; |
| int maxVertexAttribs = 0; |
| int maxClipPlane = 0; |
| int maxTexUnits = 0; |
| int maxTexImageUnits = 0; |
| int maxTexSize = 0; |
| int maxCombinedTexImageUnits = 0; |
| |
| int maxTransformFeedbackSeparateAttribs = 0; |
| int maxUniformBufferBindings = 0; |
| int maxAtomicCounterBufferBindings = 0; |
| int maxShaderStorageBufferBindings = 0; |
| int maxVertexAttribBindings = 0; |
| |
| int maxDrawBuffers = 1; |
| |
| Version glslVersion; |
| bool GL_EXT_TEXTURE_FORMAT_BGRA8888 = false; |
| bool GL_EXT_FRAMEBUFFER_OBJECT = false; |
| bool GL_ARB_VERTEX_BLEND = false; |
| bool GL_ARB_MATRIX_PALETTE = false; |
| bool GL_EXT_PACKED_DEPTH_STENCIL = false; |
| bool GL_OES_READ_FORMAT = false; |
| bool GL_ARB_HALF_FLOAT_PIXEL = false; |
| bool GL_NV_HALF_FLOAT = false; |
| bool GL_ARB_HALF_FLOAT_VERTEX = false; |
| bool GL_SGIS_GENERATE_MIPMAP = false; |
| bool GL_ARB_ES2_COMPATIBILITY = false; |
| bool GL_OES_STANDARD_DERIVATIVES = false; |
| bool GL_OES_TEXTURE_NPOT = false; |
| bool GL_OES_RGB8_RGBA8 = false; |
| bool ext_GL_OES_texture_buffer = false; |
| |
| bool ext_GL_EXT_color_buffer_float = false; |
| bool ext_GL_EXT_color_buffer_half_float = false; |
| bool ext_GL_EXT_shader_framebuffer_fetch = false; |
| bool ext_GL_EXT_texture_buffer = false; |
| bool ext_GL_EXT_draw_buffers_indexed = false; |
| |
| bool ext_GL_EXT_memory_object = false; |
| bool ext_GL_EXT_semaphore = false; |
| |
| bool ext_GL_KHR_texture_compression_astc_ldr = false; |
| |
| bool textureBufferAny() const { return ext_GL_OES_texture_buffer || ext_GL_EXT_texture_buffer; } |
| |
| bool hasEtc2Support = false; |
| bool hasAstcSupport = false; |
| bool hasBptcSupport = false; |
| bool hasS3tcSupport = false; |
| bool hasRgtcSupport = false; |
| }; |
| |
| struct ArrayData { |
| void* data = nullptr; |
| GLenum type = 0; |
| unsigned int stride = 0; |
| bool allocated = false; |
| }; |
| |
| struct BlendState { |
| GLboolean bEnable = GL_FALSE; |
| GLenum blendEquationRgb = GL_FUNC_ADD; |
| GLenum blendEquationAlpha = GL_FUNC_ADD; |
| |
| GLenum blendSrcRgb = GL_ONE; |
| GLenum blendDstRgb = GL_ZERO; |
| GLenum blendSrcAlpha = GL_ONE; |
| GLenum blendDstAlpha = GL_ZERO; |
| GLboolean colorMaskR = GL_TRUE; |
| GLboolean colorMaskG = GL_TRUE; |
| GLboolean colorMaskB = GL_TRUE; |
| GLboolean colorMaskA = GL_TRUE; |
| }; |
| |
| struct BufferBinding { |
| GLuint buffer = 0; |
| GLintptr offset = 0; |
| GLsizeiptr size = 0; |
| GLintptr stride = 0; |
| GLuint divisor = 0; |
| bool isBindBase = false; |
| void onLoad(android::base::Stream* stream); |
| void onSave(android::base::Stream* stream) const; |
| }; |
| |
| typedef std::vector<GLESpointer> VertexAttribInfoVector; |
| typedef std::vector<BufferBinding> VertexAttribBindingVector; |
| |
| struct VAOState { |
| VAOState() : VAOState(0, NULL, 0) { } |
| VAOState(GLuint ibo, ArraysMap* arr, int numVertexAttribBindings) : |
| element_array_buffer_binding(ibo), |
| vertexAttribInfo(numVertexAttribBindings), |
| bindingState(numVertexAttribBindings), |
| everBound(false), |
| legacy(arr != nullptr), |
| arraysMap(arr) { } |
| VAOState(android::base::Stream* stream); |
| GLuint element_array_buffer_binding; |
| VertexAttribInfoVector vertexAttribInfo; |
| VertexAttribBindingVector bindingState; |
| bool bufferBacked; |
| bool everBound; |
| bool legacy = false; |
| std::unique_ptr<ArraysMap> arraysMap; |
| void onSave(android::base::Stream* stream) const; |
| }; |
| |
| typedef std::unordered_map<GLuint, VAOState> VAOStateMap; |
| |
| struct VAOStateRef { |
| VAOStateRef() { } |
| VAOStateRef(VAOStateMap::iterator iter) : it(iter) { } |
| GLuint vaoId() const { return it->first; } |
| GLuint& iboId() { return it->second.element_array_buffer_binding; } |
| |
| const VertexAttribInfoVector& attribInfo_const() const { |
| return it->second.vertexAttribInfo; |
| } |
| |
| VertexAttribInfoVector& attribInfo() { |
| return it->second.vertexAttribInfo; |
| } |
| |
| ArraysMap::iterator begin() { |
| return it->second.arraysMap->begin(); |
| } |
| ArraysMap::iterator end() { |
| return it->second.arraysMap->end(); |
| } |
| ArraysMap::iterator find(GLenum arrType) { |
| return it->second.arraysMap->find(arrType); |
| } |
| GLESpointer*& operator[](size_t k) { |
| ArraysMap* map = it->second.arraysMap.get(); |
| return (*map)[k]; |
| } |
| VertexAttribBindingVector& bufferBindings() { |
| return it->second.bindingState; |
| } |
| void setEverBound() { |
| it->second.everBound = true; |
| } |
| bool isEverBound() { |
| return it->second.everBound; |
| } |
| VAOStateMap::iterator it; |
| }; |
| |
| class FramebufferData; |
| |
| class GLESConversionArrays |
| { |
| public: |
| void setArr(void* data,unsigned int stride,GLenum type); |
| void allocArr(unsigned int size,GLenum type); |
| ArrayData& operator[](int i); |
| void* getCurrentData(); |
| ArrayData& getCurrentArray(); |
| unsigned int getCurrentIndex(); |
| void operator++(); |
| |
| ~GLESConversionArrays(); |
| private: |
| std::unordered_map<GLenum,ArrayData> m_arrays; |
| unsigned int m_current = 0; |
| }; |
| |
| |
| class GLEScontext{ |
| public: |
| GLEScontext(); |
| GLEScontext(GlobalNameSpace* globalNameSpace, android::base::Stream* stream, |
| GlLibrary* glLib); |
| virtual void init(); |
| static void initGlobal(EGLiface* eglIface); |
| GLenum getGLerror(); |
| void setGLerror(GLenum err); |
| void setShareGroup(ShareGroupPtr grp){m_shareGroup = std::move(grp);}; |
| const ShareGroupPtr& shareGroup() const { return m_shareGroup; } |
| virtual void setActiveTexture(GLenum tex); |
| unsigned int getActiveTextureUnit() const { return m_activeTexture; } |
| unsigned int getBindedTexture(GLenum target); |
| unsigned int getBindedTexture(GLenum unit,GLenum target); |
| void setBindedTexture(GLenum target,unsigned int tex); |
| bool isTextureUnitEnabled(GLenum unit); |
| void setTextureEnabled(GLenum target, GLenum enable); |
| ObjectLocalName getDefaultTextureName(GLenum target); |
| ObjectLocalName getTextureLocalName(GLenum target, unsigned int tex); |
| bool isInitialized() { return m_initialized; }; |
| bool needRestore(); |
| |
| bool isArrEnabled(GLenum); |
| virtual void enableArr(GLenum arr,bool enable); |
| |
| void addVertexArrayObjects(GLsizei n, GLuint* arrays); |
| void removeVertexArrayObjects(GLsizei n, const GLuint* arrays); |
| bool setVertexArrayObject(GLuint array); |
| void setVAOEverBound(); |
| GLuint getVertexArrayObject() const; |
| bool vertexAttributesBufferBacked(); |
| const GLvoid* setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data, GLsizei dataSize, bool normalize = false, bool isInt = false); |
| virtual const GLESpointer* getPointer(GLenum arrType); |
| virtual void setupArraysPointers(GLESConversionArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct, bool* needEnablingPostDraw) = 0; |
| |
| static void prepareCoreProfileEmulatedTexture(TextureData* texData, bool is3d, GLenum target, |
| GLenum format, GLenum type, |
| GLint* internalformat_out, GLenum* format_out); |
| |
| GLuint bindBuffer(GLenum target,GLuint buffer); // returns global name for dispatcher |
| virtual void bindIndexedBuffer(GLenum target, |
| GLuint index, |
| GLuint buffer, |
| GLintptr offset, |
| GLsizeiptr size, |
| GLintptr stride = 0, |
| bool isBindBase = false); |
| virtual void bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer); |
| virtual void unbindBuffer(GLuint buffer); |
| bool isBuffer(GLuint buffer); |
| bool isBindedBuffer(GLenum target); |
| GLvoid* getBindedBuffer(GLenum target); |
| GLuint getBuffer(GLenum target); |
| virtual GLuint getIndexedBuffer(GLenum target, GLuint index); |
| void getBufferSize(GLenum target,GLint* param); |
| void getBufferSizeById(GLuint buffer,GLint* param); |
| void getBufferUsage(GLenum target,GLint* param); |
| bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage); |
| bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data); |
| const char * getExtensionString(bool isGles1); |
| const char * getVendorString(bool isGles1) const; |
| const char * getRendererString(bool isGles1) const; |
| const char * getVersionString(bool isGles1) const; |
| void getGlobalLock(); |
| void releaseGlobalLock(); |
| virtual const GLSupport* getCaps() const = 0; |
| static GLSupport* getCapsGlobal(){return &s_glSupport;}; |
| static bool vulkanInteropSupported() { |
| return s_glSupport.ext_GL_EXT_memory_object && |
| s_glSupport.ext_GL_EXT_semaphore; |
| } |
| static bool shaderFramebufferFetchSupported() { |
| return s_glSupport.ext_GL_EXT_shader_framebuffer_fetch; |
| } |
| virtual ~GLEScontext(); |
| virtual int getMaxTexUnits() = 0; |
| virtual int getMaxCombinedTexUnits() { return getMaxTexUnits(); } |
| virtual void drawValidate(void); |
| |
| // Default FBO emulation. Do not call this from GLEScontext context; |
| // it needs dynamic dispatch (from GLEScmContext or GLESv2Context DLLs) |
| // to pick up on the right functions. |
| virtual void initDefaultFBO( |
| GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples, |
| GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId, |
| GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthStencilFormat, GLint readMultisamples, |
| GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId); |
| void initEmulatedEGLSurface(GLint width, GLint height, |
| GLint colorFormat, GLint depthstencilFormat, GLint multisamples, |
| GLuint rboColor, GLuint rboDepth); |
| |
| GLuint getDefaultFBOGlobalName() const { return m_defaultFBO; } |
| bool isDefaultFBOBound(GLenum target) const { return !getFramebufferBinding(target); } |
| bool hasEmulatedDefaultFBO() const { return m_defaultFBO != 0; } |
| |
| int getDefaultFBOColorFormat() const { return m_defaultFBOColorFormat; } |
| int getDefaultFBOWidth() const { return m_defaultFBOWidth; } |
| int getDefaultFBOHeight() const { return m_defaultFBOHeight; } |
| int getDefaultFBOMultisamples() const { return m_defaultFBOSamples; } |
| |
| void setRenderbufferBinding(GLuint rb) { m_renderbuffer = rb; } |
| GLuint getRenderbufferBinding() const { return m_renderbuffer; } |
| void setFramebufferBinding(GLenum target, GLuint fb) { |
| switch (target) { |
| case GL_READ_FRAMEBUFFER: |
| m_readFramebuffer = fb; |
| break; |
| case GL_DRAW_FRAMEBUFFER: |
| m_drawFramebuffer = fb; |
| break; |
| case GL_FRAMEBUFFER: |
| m_readFramebuffer = fb; |
| m_drawFramebuffer = fb; |
| break; |
| default: |
| m_drawFramebuffer = fb; |
| break; |
| } |
| } |
| GLuint getFramebufferBinding(GLenum target) const { |
| switch (target) { |
| case GL_READ_FRAMEBUFFER: |
| return m_readFramebuffer; |
| case GL_DRAW_FRAMEBUFFER: |
| case GL_FRAMEBUFFER: |
| return m_drawFramebuffer; |
| } |
| return m_drawFramebuffer; |
| } |
| |
| void setEnable(GLenum item, bool isEnable); |
| void setEnablei(GLenum cap, GLuint index, bool isEnable); |
| bool isEnabled(GLenum item) const; |
| void setBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); |
| void setBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha); |
| void setBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, |
| GLenum srcAlpha, GLenum dstAlpha); |
| void setBlendFuncSeparatei(GLenum buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); |
| void setPixelStorei(GLenum pname, GLint param); |
| |
| void setViewport(GLint x, GLint y, GLsizei width, GLsizei height); |
| void getViewport(GLint* params); |
| void setPolygonOffset(GLfloat factor, GLfloat units); |
| void setScissor(GLint x, GLint y, GLsizei width, GLsizei height); |
| void setCullFace(GLenum mode); |
| void setFrontFace(GLenum mode); |
| |
| void setDepthFunc(GLenum func); |
| void setDepthMask(GLboolean flag); |
| void setDepthRangef(GLclampf zNear, GLclampf zFar); |
| void setLineWidth(GLfloat lineWidth); |
| void setSampleCoverage(GLclampf value, GLboolean invert); |
| |
| void setStencilFuncSeparate(GLenum face, GLenum func, GLint ref, |
| GLuint mask); |
| void setStencilMaskSeparate(GLenum face, GLuint mask); |
| void setStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, |
| GLenum zpass); |
| |
| void setColorMask(GLboolean red, GLboolean green, GLboolean blue, |
| GLboolean alpha); |
| |
| void setColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); |
| |
| void setClearColor(GLclampf red, GLclampf green, GLclampf blue, |
| GLclampf alpha); |
| void setClearDepth(GLclampf depth); |
| void setClearStencil(GLint s); |
| |
| // Core profile doesn't support GL_GENERATE_MIPMAP_HINT, |
| // so just emulate it here with no-ops. |
| void setHint(GLenum target, GLenum mode) { |
| m_hints[target] = mode; |
| } |
| GLenum getHint(GLenum target) const { |
| return android::base::findOrDefault(m_hints, target, GL_DONT_CARE); |
| } |
| |
| static GLDispatch& dispatcher(){return s_glDispatch;}; |
| static EGLiface* eglIface(); |
| static void initEglIface(EGLiface* iface); |
| |
| static int getMaxLights(){return s_glSupport.maxLights;} |
| static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;} |
| static int getMaxTexSize(){return s_glSupport.maxTexSize;} |
| static Version glslVersion(){return s_glSupport.glslVersion;} |
| static bool isAutoMipmapSupported(){return s_glSupport.GL_SGIS_GENERATE_MIPMAP;} |
| static TextureTarget GLTextureTargetToLocal(GLenum target); |
| static unsigned int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices); |
| |
| virtual bool glGetIntegerv(GLenum pname, GLint *params); |
| virtual bool glGetBooleanv(GLenum pname, GLboolean *params); |
| virtual bool glGetFloatv(GLenum pname, GLfloat *params); |
| virtual bool glGetFixedv(GLenum pname, GLfixed *params); |
| |
| int getMajorVersion() const { return m_glesMajorVersion; } |
| int getMinorVersion() const { return m_glesMinorVersion; } |
| |
| // FBO |
| void initFBONameSpace(GlobalNameSpace* globalNameSpace, |
| android::base::Stream* stream); |
| bool isFBO(ObjectLocalName p_localName); |
| ObjectLocalName genFBOName(ObjectLocalName p_localName = 0, |
| bool genLocal = 0); |
| void setFBOData(ObjectLocalName p_localName, ObjectDataPtr data); |
| void setDefaultFBODrawBuffer(GLenum buffer); |
| void setDefaultFBOReadBuffer(GLenum buffer); |
| void deleteFBO(ObjectLocalName p_localName); |
| FramebufferData* getFBOData(ObjectLocalName p_localName) const; |
| ObjectDataPtr getFBODataPtr(ObjectLocalName p_localName) const; |
| unsigned int getFBOGlobalName(ObjectLocalName p_localName) const; |
| ObjectLocalName getFBOLocalName(unsigned int p_globalName) const; |
| int queryCurrFboBits(ObjectLocalName localFboName, GLenum pname); |
| |
| // Texture emulation |
| void copyTexImageWithEmulation( |
| TextureData* texData, |
| bool isSubImage, |
| GLenum target, |
| GLint level, |
| GLenum internalformat, |
| GLint xoffset, GLint yoffset, |
| GLint x, GLint y, |
| GLsizei width, GLsizei height, |
| GLint border); |
| |
| // Primitive restart emulation |
| void setPrimitiveRestartEnabled(bool enabled); |
| bool primitiveRestartEnabled() const { |
| return m_primitiveRestartEnabled; |
| } |
| void updatePrimitiveRestartIndex(GLenum type); |
| |
| bool isVAO(ObjectLocalName p_localName); |
| ObjectLocalName genVAOName(ObjectLocalName p_localName = 0, |
| bool genLocal = 0); |
| void deleteVAO(ObjectLocalName p_localName); |
| unsigned int getVAOGlobalName(ObjectLocalName p_localName); |
| ObjectLocalName getVAOLocalName(unsigned int p_globalName); |
| |
| // Snapshot save |
| virtual void onSave(android::base::Stream* stream) const; |
| virtual void postSave(android::base::Stream* stream) const; |
| virtual ObjectDataPtr loadObject(NamedObjectType type, |
| ObjectLocalName localName, android::base::Stream* stream) const; |
| // postLoad is triggered after setting up ShareGroup |
| virtual void postLoad(); |
| virtual void restore(); |
| |
| bool isCoreProfile() const { return m_coreProfile; } |
| void setCoreProfile(bool core) { m_coreProfile = core; } |
| |
| // Utility functions for emulation |
| static GLuint compileAndValidateCoreShader(GLenum shaderType, const char* src); |
| static GLuint linkAndValidateProgram(GLuint vshader, GLuint fshader); |
| |
| bool contextNeedsRestore() const { |
| return m_needRestoreFromSnapshot; |
| } |
| |
| void blitFromReadBufferToTextureFlipped(GLuint globalTexObj, |
| GLuint width, GLuint height, |
| GLint internalFormat, GLenum format, GLenum type); |
| void blitFromReadBufferToEGLImage(EGLImage image, GLint internalFormat, int width, int height); |
| |
| protected: |
| void initDefaultFboImpl( |
| GLint width, GLint height, |
| GLint colorFormat, GLint depthstencilFormat, |
| GLint multisamples, |
| GLuint* eglSurfaceRBColorId, |
| GLuint* eglSurfaceRBDepthId); |
| |
| virtual void postLoadRestoreShareGroup(); |
| virtual void postLoadRestoreCtx(); |
| |
| static void buildStrings(int major, int minor, const char* baseVendor, const char* baseRenderer, const char* baseVersion, const char* version); |
| |
| void freeVAOState(); |
| virtual void addVertexArrayObject(GLuint array); |
| void removeVertexArrayObject(GLuint array); |
| |
| virtual bool needConvert(GLESConversionArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) = 0; |
| void convertDirect(GLESConversionArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p); |
| void convertDirectVBO(GLESConversionArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p); |
| void convertIndirect(GLESConversionArrays& fArrs,GLsizei count,GLenum type,const GLvoid* indices,GLenum array_id,GLESpointer* p); |
| void convertIndirectVBO(GLESConversionArrays& fArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p); |
| static void initCapsLocked(const GLubyte * extensionString, GLSupport& glSupport); |
| virtual void initExtensionString() =0; |
| |
| bool m_needRestoreFromSnapshot = false; |
| static android::base::Lock s_lock; |
| static GLDispatch s_glDispatch; |
| bool m_initialized = false; |
| unsigned int m_activeTexture = 0; |
| |
| VAOStateMap m_vaoStateMap; |
| VAOStateRef m_currVaoState; |
| // Buffer binding state |
| GLuint m_copyReadBuffer = 0; |
| GLuint m_copyWriteBuffer = 0; |
| GLuint m_pixelPackBuffer = 0; |
| GLuint m_pixelUnpackBuffer = 0; |
| GLuint m_transformFeedbackBuffer = 0; |
| GLuint m_uniformBuffer = 0; |
| GLuint m_atomicCounterBuffer = 0; |
| GLuint m_dispatchIndirectBuffer = 0; |
| GLuint m_drawIndirectBuffer = 0; |
| GLuint m_shaderStorageBuffer = 0; |
| GLuint m_textureBuffer = 0; |
| std::vector<BufferBinding> m_indexedTransformFeedbackBuffers; |
| std::vector<BufferBinding> m_indexedUniformBuffers; |
| std::vector<BufferBinding> m_indexedAtomicCounterBuffers; |
| std::vector<BufferBinding> m_indexedShaderStorageBuffers; |
| |
| bool m_isViewport = false; |
| GLint m_viewportX = 0; |
| GLint m_viewportY = 0; |
| GLsizei m_viewportWidth = 0; |
| GLsizei m_viewportHeight = 0; |
| |
| GLfloat m_polygonOffsetFactor = 0.0f; |
| GLfloat m_polygonOffsetUnits = 0.0f; |
| |
| bool m_isScissor = false; |
| GLint m_scissorX = 0; |
| GLint m_scissorY = 0; |
| GLsizei m_scissorWidth = 0; |
| GLsizei m_scissorHeight = 0; |
| |
| std::unordered_map<GLenum, bool> m_glEnableList = std::unordered_map<GLenum, bool>(); |
| |
| std::vector<BlendState> m_blendStates; |
| |
| std::unordered_map<GLenum, GLint> m_glPixelStoreiList; |
| |
| GLenum m_cullFace = GL_BACK; |
| GLenum m_frontFace = GL_CCW; |
| |
| GLenum m_depthFunc = GL_LESS; |
| GLboolean m_depthMask = GL_TRUE; |
| GLclampf m_zNear = 0.0f; |
| GLclampf m_zFar = 1.0f; |
| |
| GLfloat m_lineWidth = 1.0f; |
| |
| GLclampf m_sampleCoverageVal = 1.0f; |
| GLboolean m_sampleCoverageInvert = GL_FALSE; |
| |
| enum { |
| StencilFront = 0, |
| StencilBack |
| }; |
| struct { |
| GLenum m_func = GL_ALWAYS; |
| GLint m_ref = 0; |
| GLuint m_funcMask = -1; // all bits set to 1 |
| GLuint m_writeMask = -1; // all bits set to 1 |
| GLenum m_sfail = GL_KEEP; |
| GLenum m_dpfail = GL_KEEP; |
| GLenum m_dppass = GL_KEEP; |
| } m_stencilStates[2]; |
| |
| GLclampf m_clearColorR = 0.0f; |
| GLclampf m_clearColorG = 0.0f; |
| GLclampf m_clearColorB = 0.0f; |
| GLclampf m_clearColorA = 0.0f; |
| |
| GLclampf m_clearDepth = 1.0f; |
| GLint m_clearStencil = 0; |
| |
| // we may run with multiple gles version contexts. |
| // for Angle based driver, es31 feature still not completed |
| // only enabled with application requires es3.1 |
| // the default context version is still es3.0. |
| // this is temporary patch. we can remove this patch if Angle ES3.1 feature completed. |
| static std::string* s_glExtensionsGles1; |
| static bool s_glExtensionsGles1Initialized; |
| static std::string* s_glExtensionsGles31; |
| static bool s_glExtensionsGles31Initialized; |
| static std::string* s_glExtensions; |
| static bool s_glExtensionsInitialized; |
| |
| // for ES1.1 |
| static GLSupport s_glSupportGles1; |
| // Common for ES2.0+ |
| static GLSupport s_glSupport; |
| // Special for ES3.1 |
| static GLSupport s_glSupportGles31; |
| |
| int m_glesMajorVersion = 1; |
| int m_glesMinorVersion = 0; |
| |
| ShareGroupPtr m_shareGroup; |
| |
| // Default FBO per-context state |
| GLuint m_defaultFBO = 0; |
| GLuint m_defaultReadFBO = 0; |
| GLuint m_defaultFboRBColor = 0; |
| GLuint m_defaultFboRBDepth = 0; |
| GLuint m_defaultReadFboRBColor = 0; |
| GLuint m_defaultReadFboRBDepth = 0; |
| GLint m_defaultFBOWidth = 0; |
| GLint m_defaultFBOHeight = 0; |
| GLint m_defaultFBOColorFormat = 0; |
| GLint m_defaultFBODepthFormat = 0; |
| GLint m_defaultFBOStencilFormat = 0; |
| GLint m_defaultFBOSamples = 0; |
| GLenum m_defaultFBODrawBuffer = GL_COLOR_ATTACHMENT0; |
| GLenum m_defaultFBOReadBuffer = GL_COLOR_ATTACHMENT0; |
| |
| // Texture emulation state |
| void initTexImageEmulation(); |
| GLuint m_textureEmulationFBO = 0; |
| GLuint m_textureEmulationTextures[2] = {}; |
| GLuint m_textureEmulationProg = 0; |
| GLuint m_textureEmulationVAO = 0; |
| GLuint m_textureEmulationVBO = 0; |
| GLuint m_textureEmulationSamplerLoc = 0; |
| |
| std::function<GLESbuffer*(GLuint)> getBufferObj |
| = [this] (GLuint bufferName) -> GLESbuffer* { |
| return (GLESbuffer*)m_shareGroup->getObjectData( |
| NamedObjectType::VERTEXBUFFER, |
| (ObjectLocalName)bufferName); |
| }; |
| |
| GLuint m_useProgram = 0; |
| |
| private: |
| |
| GLenum m_glError = GL_NO_ERROR; |
| int m_maxTexUnits; |
| unsigned int m_maxUsedTexUnit = 0; |
| textureUnitState* m_texState = nullptr; |
| unsigned int m_arrayBuffer = 0; |
| unsigned int m_elementBuffer = 0; |
| GLuint m_renderbuffer = 0; |
| GLuint m_drawFramebuffer = 0; |
| GLuint m_readFramebuffer = 0; |
| |
| static std::string s_glVendorGles1; |
| static std::string s_glRendererGles1; |
| static std::string s_glVersionGles1; |
| |
| static std::string s_glVendorGles31; |
| static std::string s_glRendererGles31; |
| static std::string s_glVersionGles31; |
| |
| static std::string s_glVendor; |
| static std::string s_glRenderer; |
| static std::string s_glVersion; |
| |
| NameSpace* m_fboNameSpace = nullptr; |
| // m_vaoNameSpace is an empty shell that holds the names but not the data |
| // TODO(yahan): consider moving the data into it? |
| NameSpace* m_vaoNameSpace = nullptr; |
| |
| bool m_coreProfile = false; |
| |
| std::unordered_map<GLenum, GLenum> m_hints; |
| |
| bool m_primitiveRestartEnabled = false; |
| |
| struct ImageBlitState { |
| GLuint program = 0; |
| GLuint samplerLoc = 0; |
| |
| GLuint vao = 0; |
| GLuint vbo = 0; |
| GLuint ibo = 0; |
| |
| GLuint fbo = 0; |
| GLuint resolveFbo = 0; |
| GLuint tex = 0; |
| |
| uint32_t width = 0; |
| uint32_t height = 0; |
| GLint internalFormat = 0; |
| uint32_t samples = 0; |
| uint32_t prevSamples = 0; |
| |
| GLuint eglImageTex = 0; |
| }; |
| |
| ImageBlitState m_blitState = {}; |
| GLint getReadBufferSamples(); |
| GLint getReadBufferInternalFormat(); |
| void getReadBufferDimensions(GLint* width, GLint* height); |
| void setupImageBlitState(); |
| bool setupImageBlitForTexture(uint32_t width, uint32_t height, |
| GLint internalFormat); |
| }; |
| |
| std::string getHostExtensionsString(GLDispatch* dispatch); |
| |
| #endif |
| |