/* * 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 #include #include #include #include static constexpr int kMaxVertexAttributes = 16; typedef std::unordered_map 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_OVR_multiview2 = false; bool ext_GL_EXT_multiview_texture_multisample = 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_clip_cull_distance = 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 VertexAttribInfoVector; typedef std::vector VertexAttribBindingVector; struct VAOState { VAOState() : VAOState(0, NULL, 0) { } VAOState(GLuint ibo, ArraysMap* arr, int numVertexAttribBindings) : element_array_buffer_binding(ibo), vertexAttribInfo(numVertexAttribBindings), bindingState(numVertexAttribBindings), bufferBacked(false), 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; void onSave(android::base::Stream* stream) const; }; typedef std::unordered_map 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 m_arrays; unsigned int m_current = 0; }; class GLEScontext{ public: GLEScontext(); GLEScontext(GlobalNameSpace* globalNameSpace, android::base::Stream* stream, GlLibrary* glLib); virtual void init(bool nativeTextureDecompressionEnabled); 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, bool nativeTextureDecompressionEnabled, 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 m_indexedTransformFeedbackBuffers; std::vector m_indexedUniformBuffers; std::vector m_indexedAtomicCounterBuffers; std::vector 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 m_glEnableList = std::unordered_map(); std::vector m_blendStates; std::unordered_map 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 getBufferObj = [this] (GLuint bufferName) -> GLESbuffer* { return (GLESbuffer*)m_shareGroup->getObjectData( NamedObjectType::VERTEXBUFFER, (ObjectLocalName)bufferName); }; GLuint m_useProgram = 0; bool m_nativeTextureDecompressionEnabled = false; 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 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