summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE
diff options
context:
space:
mode:
authorMiguel Costa <miguel.costa@qt.io>2018-06-26 16:56:45 +0200
committerAndre de la Rocha <andre.rocha@qt.io>2018-10-13 21:36:35 +0000
commit0a7aebadfbb3534284546aa3ca8612314c08f136 (patch)
treee94ee33ae3bb9b96fc3047c6455d47ac4920bfbf /src/3rdparty/angle/src/libANGLE
parent656e89f875ad2008ca16cc673b687a22daa294c9 (diff)
Update ANGLE to chromium/3280
Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE')
-rw-r--r--src/3rdparty/angle/src/libANGLE/AttributeMap.cpp85
-rw-r--r--src/3rdparty/angle/src/libANGLE/AttributeMap.h22
-rw-r--r--src/3rdparty/angle/src/libANGLE/BinaryStream.h97
-rw-r--r--src/3rdparty/angle/src/libANGLE/Buffer.cpp187
-rw-r--r--src/3rdparty/angle/src/libANGLE/Buffer.h100
-rw-r--r--src/3rdparty/angle/src/libANGLE/Caps.cpp940
-rw-r--r--src/3rdparty/angle/src/libANGLE/Caps.h291
-rw-r--r--src/3rdparty/angle/src/libANGLE/Compiler.cpp143
-rw-r--r--src/3rdparty/angle/src/libANGLE/Compiler.h20
-rw-r--r--src/3rdparty/angle/src/libANGLE/Config.cpp36
-rw-r--r--src/3rdparty/angle/src/libANGLE/Config.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/Constants.h40
-rw-r--r--src/3rdparty/angle/src/libANGLE/Context.cpp5684
-rw-r--r--src/3rdparty/angle/src/libANGLE/Context.h1039
-rw-r--r--src/3rdparty/angle/src/libANGLE/ContextState.cpp839
-rw-r--r--src/3rdparty/angle/src/libANGLE/ContextState.h164
-rw-r--r--src/3rdparty/angle/src/libANGLE/Data.cpp56
-rw-r--r--src/3rdparty/angle/src/libANGLE/Data.h72
-rw-r--r--src/3rdparty/angle/src/libANGLE/Debug.cpp24
-rw-r--r--src/3rdparty/angle/src/libANGLE/Debug.h9
-rw-r--r--src/3rdparty/angle/src/libANGLE/Device.cpp21
-rw-r--r--src/3rdparty/angle/src/libANGLE/Display.cpp812
-rw-r--r--src/3rdparty/angle/src/libANGLE/Display.h124
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.cpp58
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.h205
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.inl32
-rw-r--r--src/3rdparty/angle/src/libANGLE/ErrorStrings.h173
-rw-r--r--src/3rdparty/angle/src/libANGLE/Fence.cpp48
-rw-r--r--src/3rdparty/angle/src/libANGLE/Fence.h16
-rw-r--r--src/3rdparty/angle/src/libANGLE/Framebuffer.cpp2021
-rw-r--r--src/3rdparty/angle/src/libANGLE/Framebuffer.h319
-rw-r--r--src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp227
-rw-r--r--src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h186
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp34
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleAllocator.h8
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.cpp229
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.h60
-rw-r--r--src/3rdparty/angle/src/libANGLE/Image.cpp205
-rw-r--r--src/3rdparty/angle/src/libANGLE/Image.h66
-rw-r--r--src/3rdparty/angle/src/libANGLE/ImageIndex.cpp130
-rw-r--r--src/3rdparty/angle/src/libANGLE/ImageIndex.h14
-rw-r--r--src/3rdparty/angle/src/libANGLE/IndexRangeCache.cpp8
-rw-r--r--src/3rdparty/angle/src/libANGLE/IndexRangeCache.h3
-rw-r--r--src/3rdparty/angle/src/libANGLE/LoggingAnnotator.cpp44
-rw-r--r--src/3rdparty/angle/src/libANGLE/LoggingAnnotator.h31
-rw-r--r--src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp772
-rw-r--r--src/3rdparty/angle/src/libANGLE/MemoryProgramCache.h130
-rw-r--r--src/3rdparty/angle/src/libANGLE/PackedGLEnums.h111
-rw-r--r--src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.cpp174
-rw-r--r--src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.h84
-rw-r--r--src/3rdparty/angle/src/libANGLE/Path.cpp78
-rw-r--r--src/3rdparty/angle/src/libANGLE/Path.h71
-rw-r--r--src/3rdparty/angle/src/libANGLE/Platform.cpp56
-rw-r--r--src/3rdparty/angle/src/libANGLE/Program.cpp2889
-rw-r--r--src/3rdparty/angle/src/libANGLE/Program.h641
-rw-r--r--src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.cpp1040
-rw-r--r--src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.h274
-rw-r--r--src/3rdparty/angle/src/libANGLE/ProgramPipeline.cpp65
-rw-r--r--src/3rdparty/angle/src/libANGLE/ProgramPipeline.h65
-rw-r--r--src/3rdparty/angle/src/libANGLE/Query.h3
-rw-r--r--src/3rdparty/angle/src/libANGLE/RefCountObject.cpp39
-rw-r--r--src/3rdparty/angle/src/libANGLE/RefCountObject.h88
-rw-r--r--src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp147
-rw-r--r--src/3rdparty/angle/src/libANGLE/Renderbuffer.h43
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceManager.cpp603
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceManager.h298
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceMap.h305
-rw-r--r--src/3rdparty/angle/src/libANGLE/Sampler.cpp73
-rw-r--r--src/3rdparty/angle/src/libANGLE/Sampler.h19
-rw-r--r--src/3rdparty/angle/src/libANGLE/Shader.cpp373
-rw-r--r--src/3rdparty/angle/src/libANGLE/Shader.h216
-rw-r--r--src/3rdparty/angle/src/libANGLE/SizedMRUCache.h174
-rw-r--r--src/3rdparty/angle/src/libANGLE/State.cpp1260
-rw-r--r--src/3rdparty/angle/src/libANGLE/State.h348
-rw-r--r--src/3rdparty/angle/src/libANGLE/Stream.cpp271
-rw-r--r--src/3rdparty/angle/src/libANGLE/Stream.h143
-rw-r--r--src/3rdparty/angle/src/libANGLE/Surface.cpp369
-rw-r--r--src/3rdparty/angle/src/libANGLE/Surface.h163
-rw-r--r--src/3rdparty/angle/src/libANGLE/Texture.cpp1509
-rw-r--r--src/3rdparty/angle/src/libANGLE/Texture.h359
-rw-r--r--src/3rdparty/angle/src/libANGLE/Thread.cpp91
-rw-r--r--src/3rdparty/angle/src/libANGLE/Thread.h51
-rw-r--r--src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp159
-rw-r--r--src/3rdparty/angle/src/libANGLE/TransformFeedback.h61
-rw-r--r--src/3rdparty/angle/src/libANGLE/Uniform.cpp185
-rw-r--r--src/3rdparty/angle/src/libANGLE/Uniform.h100
-rw-r--r--src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp (renamed from src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp)329
-rw-r--r--src/3rdparty/angle/src/libANGLE/VaryingPacking.h (renamed from src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.h)99
-rw-r--r--src/3rdparty/angle/src/libANGLE/Version.h15
-rw-r--r--src/3rdparty/angle/src/libANGLE/Version.inl38
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexArray.cpp235
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexArray.h188
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp122
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexAttribute.h84
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexAttribute.inl47
-rw-r--r--src/3rdparty/angle/src/libANGLE/Workarounds.h29
-rw-r--r--src/3rdparty/angle/src/libANGLE/WorkerThread.cpp157
-rw-r--r--src/3rdparty/angle/src/libANGLE/WorkerThread.h284
-rw-r--r--src/3rdparty/angle/src/libANGLE/angletypes.cpp162
-rw-r--r--src/3rdparty/angle/src/libANGLE/angletypes.h307
-rw-r--r--src/3rdparty/angle/src/libANGLE/angletypes.inl47
-rw-r--r--src/3rdparty/angle/src/libANGLE/entry_points_enum_autogen.h336
-rw-r--r--src/3rdparty/angle/src/libANGLE/es3_copy_conversion_formats.json44
-rw-r--r--src/3rdparty/angle/src/libANGLE/es3_copy_conversion_table_autogen.cpp171
-rw-r--r--src/3rdparty/angle/src/libANGLE/es3_format_type_combinations.json171
-rw-r--r--src/3rdparty/angle/src/libANGLE/features.h12
-rw-r--r--src/3rdparty/angle/src/libANGLE/format_map_autogen.cpp1570
-rw-r--r--src/3rdparty/angle/src/libANGLE/format_map_data.json142
-rw-r--r--src/3rdparty/angle/src/libANGLE/formatutils.cpp1365
-rw-r--r--src/3rdparty/angle/src/libANGLE/formatutils.h141
-rw-r--r--src/3rdparty/angle/src/libANGLE/histogram_macros.h67
-rw-r--r--src/3rdparty/angle/src/libANGLE/packed_gl_enums.json35
-rw-r--r--src/3rdparty/angle/src/libANGLE/params.cpp68
-rw-r--r--src/3rdparty/angle/src/libANGLE/params.h228
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryconversions.cpp206
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryconversions.h87
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryutils.cpp1916
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryutils.h162
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h49
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/BufferImpl_mock.h32
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.cpp119
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.h186
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp25
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h60
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/EGLImplFactory.h68
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Format.h105
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Format_ID_autogen.inl147
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Format_table_autogen.cpp434
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h54
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h65
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl_mock.h57
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/GLImplFactory.h93
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Image.h77
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ImageImpl.h16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ImageImpl_mock.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h74
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/PathImpl.h36
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp152
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h66
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl_mock.h27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramPipelineImpl.h32
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl_mock.h15
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp62
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Renderer.h121
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SamplerImpl.h20
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/StreamProducerImpl.h39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp8
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SyncImpl.h (renamed from src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h)11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.cpp63
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h136
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TextureImpl_mock.h116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h9
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h8
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h74
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/angle_format_data.json24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/angle_format_map.json132
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp208
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h54
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp195
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp714
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h123
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp89
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.h27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp305
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h83
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp86
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp30
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h45
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp250
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h42
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp23
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp2199
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h329
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp77
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h25
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp703
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h391
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SamplerD3D.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp100
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h7
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp274
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h97
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.cpp34
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h55
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp3088
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h864
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp46
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp347
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp750
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h108
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h66
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp22
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl32
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp2486
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h230
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp1379
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h174
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp1152
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h105
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp405
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h155
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp47
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp107
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp461
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h78
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp591
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h67
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp62
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h23
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp464
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h142
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h97
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp205
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h34
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp363
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h47
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp521
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h137
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp359
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h90
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp4100
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h573
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp533
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h366
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp111
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h45
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp2797
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h484
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp102
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp756
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h123
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp3701
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h555
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp124
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h60
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp9
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp413
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h82
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp149
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h25
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl45
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json118
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp516
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json623
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp1896
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h5
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp1142
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h56
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp170
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json1116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp2098
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp2461
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h375
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl644
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl131
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl56
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h155
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json77
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h51
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp203
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json1199
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json78
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h89
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp3037
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h85
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp (renamed from src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp)147
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h53
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp67
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h48
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp131
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp126
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h51
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp63
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp410
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h84
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp82
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h46
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp303
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h151
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp19
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp201
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp303
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h50
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp33
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp76
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h20
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp3
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp2164
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h407
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp98
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp123
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h30
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp219
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h84
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp94
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h18
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp46
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h1
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp321
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp104
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps34
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs18
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp147
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h28
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h28
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl266
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h1999
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp697
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h201
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl156
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp125
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp1435
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.h140
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/driver_utils.cpp120
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/driver_utils.h73
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/load_functions_data.json602
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/load_functions_table.h22
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp2459
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.cpp549
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.h254
-rw-r--r--src/3rdparty/angle/src/libANGLE/signal_utils.h187
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationEGL.cpp2013
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationEGL.h119
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES.cpp5533
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES.h573
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES2.cpp6313
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES2.h607
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES3.cpp3580
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES3.h415
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES31.cpp1786
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES31.h325
381 files changed, 90083 insertions, 41971 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp
index 651a012037..e10d3add7c 100644
--- a/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp
+++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp
@@ -6,6 +6,8 @@
#include "libANGLE/AttributeMap.h"
+#include "common/debug.h"
+
namespace egl
{
@@ -13,33 +15,61 @@ AttributeMap::AttributeMap()
{
}
-AttributeMap::AttributeMap(const EGLint *attributes)
-{
- if (attributes)
- {
- for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
- {
- insert(curAttrib[0], curAttrib[1]);
- }
- }
-}
+AttributeMap::AttributeMap(const AttributeMap &other) = default;
-void AttributeMap::insert(EGLint key, EGLint value)
+AttributeMap::~AttributeMap() = default;
+
+void AttributeMap::insert(EGLAttrib key, EGLAttrib value)
{
mAttributes[key] = value;
}
-bool AttributeMap::contains(EGLint key) const
+bool AttributeMap::contains(EGLAttrib key) const
{
return (mAttributes.find(key) != mAttributes.end());
}
-EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
+EGLAttrib AttributeMap::get(EGLAttrib key) const
+{
+ auto iter = mAttributes.find(key);
+ ASSERT(iter != mAttributes.end());
+ return iter->second;
+}
+
+EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
{
- std::map<EGLint, EGLint>::const_iterator iter = mAttributes.find(key);
+ auto iter = mAttributes.find(key);
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
}
+EGLint AttributeMap::getAsInt(EGLAttrib key) const
+{
+ return static_cast<EGLint>(get(key));
+}
+
+EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
+{
+ return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
+}
+
+bool AttributeMap::isEmpty() const
+{
+ return mAttributes.empty();
+}
+
+std::vector<EGLint> AttributeMap::toIntVector() const
+{
+ std::vector<EGLint> ret;
+ for (const auto &pair : mAttributes)
+ {
+ ret.push_back(static_cast<EGLint>(pair.first));
+ ret.push_back(static_cast<EGLint>(pair.second));
+ }
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
AttributeMap::const_iterator AttributeMap::begin() const
{
return mAttributes.begin();
@@ -50,4 +80,31 @@ AttributeMap::const_iterator AttributeMap::end() const
return mAttributes.end();
}
+// static
+AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes)
+{
+ AttributeMap map;
+ if (attributes)
+ {
+ for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ map.insert(static_cast<EGLAttrib>(curAttrib[0]), static_cast<EGLAttrib>(curAttrib[1]));
+ }
+ }
+ return map;
+}
+
+// static
+AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes)
+{
+ AttributeMap map;
+ if (attributes)
+ {
+ for (const EGLAttrib *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ map.insert(curAttrib[0], curAttrib[1]);
+ }
+ }
+ return map;
+}
}
diff --git a/src/3rdparty/angle/src/libANGLE/AttributeMap.h b/src/3rdparty/angle/src/libANGLE/AttributeMap.h
index 56f1684415..eddc1b72d0 100644
--- a/src/3rdparty/angle/src/libANGLE/AttributeMap.h
+++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.h
@@ -11,6 +11,7 @@
#include <EGL/egl.h>
#include <map>
+#include <vector>
namespace egl
{
@@ -19,19 +20,28 @@ class AttributeMap final
{
public:
AttributeMap();
- explicit AttributeMap(const EGLint *attributes);
+ AttributeMap(const AttributeMap &other);
+ ~AttributeMap();
- void insert(EGLint key, EGLint value);
- bool contains(EGLint key) const;
- EGLint get(EGLint key, EGLint defaultValue) const;
+ void insert(EGLAttrib key, EGLAttrib value);
+ bool contains(EGLAttrib key) const;
+ EGLAttrib get(EGLAttrib key) const;
+ EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
+ EGLint getAsInt(EGLAttrib key) const;
+ EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const;
+ bool isEmpty() const;
+ std::vector<EGLint> toIntVector() const;
- typedef std::map<EGLint, EGLint>::const_iterator const_iterator;
+ typedef std::map<EGLAttrib, EGLAttrib>::const_iterator const_iterator;
const_iterator begin() const;
const_iterator end() const;
+ static AttributeMap CreateFromIntArray(const EGLint *attributes);
+ static AttributeMap CreateFromAttribArray(const EGLAttrib *attributes);
+
private:
- std::map<EGLint, EGLint> mAttributes;
+ std::map<EGLAttrib, EGLAttrib> mAttributes;
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/BinaryStream.h b/src/3rdparty/angle/src/libANGLE/BinaryStream.h
index 3e6ccc7446..3e4c0934cf 100644
--- a/src/3rdparty/angle/src/libANGLE/BinaryStream.h
+++ b/src/3rdparty/angle/src/libANGLE/BinaryStream.h
@@ -9,25 +9,13 @@
#ifndef LIBANGLE_BINARYSTREAM_H_
#define LIBANGLE_BINARYSTREAM_H_
-#include "common/angleutils.h"
-#include "common/mathutil.h"
-
#include <cstddef>
#include <string>
#include <vector>
#include <stdint.h>
-template <typename T>
-void StaticAssertIsFundamental()
-{
- // c++11 STL is not available on OSX or Android
-#if !defined(ANGLE_PLATFORM_APPLE) && !defined(ANGLE_PLATFORM_ANDROID)
- static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
-#else
- union { T dummy; } dummy;
- static_cast<void>(dummy);
-#endif
-}
+#include "common/angleutils.h"
+#include "common/mathutil.h"
namespace gl
{
@@ -58,6 +46,16 @@ class BinaryInputStream : angle::NonCopyable
*outValue = readInt<IntT>();
}
+ template <class IntT, class VectorElementT>
+ void readIntVector(std::vector<VectorElementT> *param)
+ {
+ unsigned int size = readInt<unsigned int>();
+ for (unsigned int index = 0; index < size; ++index)
+ {
+ param->push_back(readInt<IntT>());
+ }
+ }
+
bool readBool()
{
int value = 0;
@@ -92,25 +90,31 @@ class BinaryInputStream : angle::NonCopyable
return;
}
- if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength)
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
{
mError = true;
return;
}
v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
- mOffset += length;
+ mOffset = checkedOffset.ValueOrDie();
}
void skip(size_t length)
{
- if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength)
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
{
mError = true;
return;
}
- mOffset += length;
+ mOffset = checkedOffset.ValueOrDie();
}
size_t offset() const
@@ -142,24 +146,27 @@ class BinaryInputStream : angle::NonCopyable
template <typename T>
void read(T *v, size_t num)
{
- StaticAssertIsFundamental<T>();
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
- if (!rx::IsUnsignedMultiplicationSafe(num, sizeof(T)))
+ angle::CheckedNumeric<size_t> checkedLength(num);
+ checkedLength *= sizeof(T);
+ if (!checkedLength.IsValid())
{
mError = true;
return;
}
- size_t length = num * sizeof(T);
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += checkedLength;
- if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength)
+ if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength)
{
mError = true;
return;
}
- memcpy(v, mData + mOffset, length);
- mOffset += length;
+ memcpy(v, mData + mOffset, checkedLength.ValueOrDie());
+ mOffset = checkedOffset.ValueOrDie();
}
template <typename T>
@@ -173,19 +180,42 @@ class BinaryInputStream : angle::NonCopyable
class BinaryOutputStream : angle::NonCopyable
{
public:
- BinaryOutputStream()
- {
- }
+ BinaryOutputStream();
+ ~BinaryOutputStream();
// writeInt also handles bool types
template <class IntT>
void writeInt(IntT param)
{
- ASSERT(rx::IsIntegerCastSafe<int>(param));
+ ASSERT(angle::IsValueInRangeForNumericType<int>(param));
int intValue = static_cast<int>(param);
write(&intValue, 1);
}
+ // Specialized writeInt for values that can also be exactly -1.
+ template <class UintT>
+ void writeIntOrNegOne(UintT param)
+ {
+ if (param == static_cast<UintT>(-1))
+ {
+ writeInt(-1);
+ }
+ else
+ {
+ writeInt(param);
+ }
+ }
+
+ template <class IntT>
+ void writeIntVector(std::vector<IntT> param)
+ {
+ writeInt(param.size());
+ for (IntT element : param)
+ {
+ writeIntOrNegOne(element);
+ }
+ }
+
void writeString(const std::string &v)
{
writeInt(v.length());
@@ -204,7 +234,7 @@ class BinaryOutputStream : angle::NonCopyable
const void* data() const
{
- return mData.size() ? &mData[0] : NULL;
+ return mData.size() ? &mData[0] : nullptr;
}
private:
@@ -213,12 +243,19 @@ class BinaryOutputStream : angle::NonCopyable
template <typename T>
void write(const T *v, size_t num)
{
- StaticAssertIsFundamental<T>();
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
const char *asBytes = reinterpret_cast<const char*>(v);
mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
}
};
+
+inline BinaryOutputStream::BinaryOutputStream()
+{
}
+inline BinaryOutputStream::~BinaryOutputStream() = default;
+
+} // namespace gl
+
#endif // LIBANGLE_BINARYSTREAM_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Buffer.cpp b/src/3rdparty/angle/src/libANGLE/Buffer.cpp
index 589735c5a8..a1ebfc1acb 100644
--- a/src/3rdparty/angle/src/libANGLE/Buffer.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Buffer.cpp
@@ -9,123 +9,148 @@
// [OpenGL ES 2.0.24] section 2.9 page 21.
#include "libANGLE/Buffer.h"
+
+#include "libANGLE/Context.h"
#include "libANGLE/renderer/BufferImpl.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/GLImplFactory.h"
namespace gl
{
-Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
- : RefCountObject(id),
- mBuffer(impl),
- mLabel(),
- mUsage(GL_STATIC_DRAW),
+BufferState::BufferState()
+ : mLabel(),
+ mUsage(BufferUsage::StaticDraw),
mSize(0),
mAccessFlags(0),
mAccess(GL_WRITE_ONLY_OES),
mMapped(GL_FALSE),
- mMapPointer(NULL),
+ mMapPointer(nullptr),
mMapOffset(0),
mMapLength(0)
{
}
+BufferState::~BufferState()
+{
+}
+
+Buffer::Buffer(rx::GLImplFactory *factory, GLuint id)
+ : RefCountObject(id), mImpl(factory->createBuffer(mState))
+{
+}
+
Buffer::~Buffer()
{
- SafeDelete(mBuffer);
+ SafeDelete(mImpl);
+}
+
+Error Buffer::onDestroy(const Context *context)
+{
+ // In tests, mImpl might be null.
+ if (mImpl)
+ mImpl->destroy(context);
+ return NoError();
}
void Buffer::setLabel(const std::string &label)
{
- mLabel = label;
+ mState.mLabel = label;
}
const std::string &Buffer::getLabel() const
{
- return mLabel;
+ return mState.mLabel;
}
-Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+Error Buffer::bufferData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage)
{
- gl::Error error = mBuffer->setData(data, size, usage);
- if (error.isError())
+ const void *dataForImpl = data;
+
+ // If we are using robust resource init, make sure the buffer starts cleared.
+ // Note: the Context is checked for nullptr because of some testing code.
+ // TODO(jmadill): Investigate lazier clearing.
+ if (context && context->getGLState().isRobustResourceInitEnabled() && !data && size > 0)
{
- return error;
+ angle::MemoryBuffer *scratchBuffer = nullptr;
+ ANGLE_TRY(context->getZeroFilledBuffer(static_cast<size_t>(size), &scratchBuffer));
+ dataForImpl = scratchBuffer->data();
}
+ ANGLE_TRY(mImpl->setData(context, target, dataForImpl, size, usage));
+
mIndexRangeCache.clear();
- mUsage = usage;
- mSize = size;
+ mState.mUsage = usage;
+ mState.mSize = size;
- return error;
+ return NoError();
}
-Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
+Error Buffer::bufferSubData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ GLintptr offset)
{
- gl::Error error = mBuffer->setSubData(data, size, offset);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(mImpl->setSubData(context, target, data, size, offset));
mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(size));
- return error;
+ return NoError();
}
-Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+Error Buffer::copyBufferSubData(const Context *context,
+ Buffer *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size)
{
- gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(
+ mImpl->copySubData(context, source->getImplementation(), sourceOffset, destOffset, size));
mIndexRangeCache.invalidateRange(static_cast<unsigned int>(destOffset), static_cast<unsigned int>(size));
- return error;
+ return NoError();
}
-Error Buffer::map(GLenum access)
+Error Buffer::map(const Context *context, GLenum access)
{
- ASSERT(!mMapped);
+ ASSERT(!mState.mMapped);
- Error error = mBuffer->map(access, &mMapPointer);
- if (error.isError())
- {
- mMapPointer = NULL;
- return error;
- }
+ mState.mMapPointer = nullptr;
+ ANGLE_TRY(mImpl->map(context, access, &mState.mMapPointer));
ASSERT(access == GL_WRITE_ONLY_OES);
- mMapped = GL_TRUE;
- mMapOffset = 0;
- mMapLength = mSize;
- mAccess = access;
- mAccessFlags = GL_MAP_WRITE_BIT;
+ mState.mMapped = GL_TRUE;
+ mState.mMapOffset = 0;
+ mState.mMapLength = mState.mSize;
+ mState.mAccess = access;
+ mState.mAccessFlags = GL_MAP_WRITE_BIT;
mIndexRangeCache.clear();
- return error;
+ return NoError();
}
-Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
+Error Buffer::mapRange(const Context *context,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
{
- ASSERT(!mMapped);
- ASSERT(offset + length <= mSize);
+ ASSERT(!mState.mMapped);
+ ASSERT(offset + length <= mState.mSize);
- Error error = mBuffer->mapRange(offset, length, access, &mMapPointer);
- if (error.isError())
- {
- mMapPointer = NULL;
- return error;
- }
+ mState.mMapPointer = nullptr;
+ ANGLE_TRY(mImpl->mapRange(context, offset, length, access, &mState.mMapPointer));
- mMapped = GL_TRUE;
- mMapOffset = static_cast<GLint64>(offset);
- mMapLength = static_cast<GLint64>(length);
- mAccess = GL_WRITE_ONLY_OES;
- mAccessFlags = access;
+ mState.mMapped = GL_TRUE;
+ mState.mMapOffset = static_cast<GLint64>(offset);
+ mState.mMapLength = static_cast<GLint64>(length);
+ mState.mAccess = GL_WRITE_ONLY_OES;
+ mState.mAccessFlags = access;
// The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid
// value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is
@@ -137,28 +162,24 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(length));
}
- return error;
+ return NoError();
}
-Error Buffer::unmap(GLboolean *result)
+Error Buffer::unmap(const Context *context, GLboolean *result)
{
- ASSERT(mMapped);
+ ASSERT(mState.mMapped);
- Error error = mBuffer->unmap(result);
- if (error.isError())
- {
- *result = GL_FALSE;
- return error;
- }
+ *result = GL_FALSE;
+ ANGLE_TRY(mImpl->unmap(context, result));
- mMapped = GL_FALSE;
- mMapPointer = NULL;
- mMapOffset = 0;
- mMapLength = 0;
- mAccess = GL_WRITE_ONLY_OES;
- mAccessFlags = 0;
+ mState.mMapped = GL_FALSE;
+ mState.mMapPointer = nullptr;
+ mState.mMapOffset = 0;
+ mState.mMapLength = 0;
+ mState.mAccess = GL_WRITE_ONLY_OES;
+ mState.mAccessFlags = 0;
- return error;
+ return NoError();
}
void Buffer::onTransformFeedback()
@@ -171,7 +192,8 @@ void Buffer::onPixelUnpack()
mIndexRangeCache.clear();
}
-Error Buffer::getIndexRange(GLenum type,
+Error Buffer::getIndexRange(const gl::Context *context,
+ GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
@@ -179,18 +201,15 @@ Error Buffer::getIndexRange(GLenum type,
{
if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange))
{
- return gl::Error(GL_NO_ERROR);
+ return NoError();
}
- Error error = mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(
+ mImpl->getIndexRange(context, type, offset, count, primitiveRestartEnabled, outRange));
mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange);
- return Error(GL_NO_ERROR);
+ return NoError();
}
-}
+} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Buffer.h b/src/3rdparty/angle/src/libANGLE/Buffer.h
index 6c951ef586..86d4a9fd6f 100644
--- a/src/3rdparty/angle/src/libANGLE/Buffer.h
+++ b/src/3rdparty/angle/src/libANGLE/Buffer.h
@@ -15,69 +15,109 @@
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/IndexRangeCache.h"
+#include "libANGLE/PackedGLEnums.h"
#include "libANGLE/RefCountObject.h"
namespace rx
{
class BufferImpl;
+class GLImplFactory;
};
namespace gl
{
+class Buffer;
+class Context;
-class Buffer final : public RefCountObject, public LabeledObject
+class BufferState final : angle::NonCopyable
{
public:
- Buffer(rx::BufferImpl *impl, GLuint id);
- virtual ~Buffer();
+ BufferState();
+ ~BufferState();
- void setLabel(const std::string &label) override;
- const std::string &getLabel() const override;
+ const std::string &getLabel();
- Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
- Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
- Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
- Error map(GLenum access);
- Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
- Error unmap(GLboolean *result);
-
- void onTransformFeedback();
- void onPixelUnpack();
-
- Error getIndexRange(GLenum type,
- size_t offset,
- size_t count,
- bool primitiveRestartEnabled,
- IndexRange *outRange) const;
-
- GLenum getUsage() const { return mUsage; }
+ BufferUsage getUsage() const { return mUsage; }
GLbitfield getAccessFlags() const { return mAccessFlags; }
GLenum getAccess() const { return mAccess; }
GLboolean isMapped() const { return mMapped; }
- GLvoid *getMapPointer() const { return mMapPointer; }
+ void *getMapPointer() const { return mMapPointer; }
GLint64 getMapOffset() const { return mMapOffset; }
GLint64 getMapLength() const { return mMapLength; }
GLint64 getSize() const { return mSize; }
- rx::BufferImpl *getImplementation() const { return mBuffer; }
-
private:
- rx::BufferImpl *mBuffer;
+ friend class Buffer;
std::string mLabel;
- GLenum mUsage;
+ BufferUsage mUsage;
GLint64 mSize;
GLbitfield mAccessFlags;
GLenum mAccess;
GLboolean mMapped;
- GLvoid *mMapPointer;
+ void *mMapPointer;
GLint64 mMapOffset;
GLint64 mMapLength;
+};
+
+class Buffer final : public RefCountObject, public LabeledObject
+{
+ public:
+ Buffer(rx::GLImplFactory *factory, GLuint id);
+ ~Buffer() override;
+ Error onDestroy(const Context *context) override;
+
+ void setLabel(const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ Error bufferData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage);
+ Error bufferSubData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ GLintptr offset);
+ Error copyBufferSubData(const Context *context,
+ Buffer *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size);
+ Error map(const Context *context, GLenum access);
+ Error mapRange(const Context *context, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ Error unmap(const Context *context, GLboolean *result);
+
+ void onTransformFeedback();
+ void onPixelUnpack();
+
+ Error getIndexRange(const gl::Context *context,
+ GLenum type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ IndexRange *outRange) const;
+
+ BufferUsage getUsage() const { return mState.mUsage; }
+ GLbitfield getAccessFlags() const { return mState.mAccessFlags; }
+ GLenum getAccess() const { return mState.mAccess; }
+ GLboolean isMapped() const { return mState.mMapped; }
+ void *getMapPointer() const { return mState.mMapPointer; }
+ GLint64 getMapOffset() const { return mState.mMapOffset; }
+ GLint64 getMapLength() const { return mState.mMapLength; }
+ GLint64 getSize() const { return mState.mSize; }
+
+ rx::BufferImpl *getImplementation() const { return mImpl; }
+
+ private:
+ BufferState mState;
+ rx::BufferImpl *mImpl;
mutable IndexRangeCache mIndexRangeCache;
};
-}
+} // namespace gl
-#endif // LIBANGLE_BUFFER_H_
+#endif // LIBANGLE_BUFFER_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Caps.cpp b/src/3rdparty/angle/src/libANGLE/Caps.cpp
index 1eb54a1589..44da2bbe27 100644
--- a/src/3rdparty/angle/src/libANGLE/Caps.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Caps.cpp
@@ -5,9 +5,12 @@
//
#include "libANGLE/Caps.h"
+
#include "common/debug.h"
#include "common/angleutils.h"
+#include "libANGLE/formatutils.h"
+
#include "angle_gl.h"
#include <algorithm>
@@ -32,6 +35,10 @@ TextureCaps::TextureCaps()
{
}
+TextureCaps::TextureCaps(const TextureCaps &other) = default;
+
+TextureCaps::~TextureCaps() = default;
+
GLuint TextureCaps::getMaxSamples() const
{
return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
@@ -56,40 +63,80 @@ GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
return 0;
}
+TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat,
+ const Version &clientVersion,
+ const Extensions &extensions)
+{
+ TextureCaps caps;
+
+ const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
+ caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions);
+ caps.renderable = internalFormatInfo.renderSupport(clientVersion, extensions);
+ caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions);
+
+ caps.sampleCounts.insert(0);
+ if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion))
+ {
+ if ((clientVersion.major >= 3 && clientVersion.minor >= 1) ||
+ (clientVersion.major >= 3 && internalFormatInfo.componentType != GL_UNSIGNED_INT &&
+ internalFormatInfo.componentType != GL_INT))
+ {
+ caps.sampleCounts.insert(4);
+ }
+ }
+
+ return caps;
+}
+
+TextureCapsMap::TextureCapsMap()
+{
+}
+
+TextureCapsMap::~TextureCapsMap()
+{
+}
+
void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
{
- mCapsMap[internalFormat] = caps;
+ angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
+ get(formatID) = caps;
}
-void TextureCapsMap::remove(GLenum internalFormat)
+void TextureCapsMap::clear()
{
- InternalFormatToCapsMap::iterator i = mCapsMap.find(internalFormat);
- if (i != mCapsMap.end())
- {
- mCapsMap.erase(i);
- }
+ mFormatData.fill(TextureCaps());
}
const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
{
- static TextureCaps defaultUnsupportedTexture;
- InternalFormatToCapsMap::const_iterator iter = mCapsMap.find(internalFormat);
- return (iter != mCapsMap.end()) ? iter->second : defaultUnsupportedTexture;
+ angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
+ return get(formatID);
}
-TextureCapsMap::const_iterator TextureCapsMap::begin() const
+const TextureCaps &TextureCapsMap::get(angle::Format::ID formatID) const
{
- return mCapsMap.begin();
+ return mFormatData[static_cast<size_t>(formatID)];
}
-TextureCapsMap::const_iterator TextureCapsMap::end() const
+TextureCaps &TextureCapsMap::get(angle::Format::ID formatID)
{
- return mCapsMap.end();
+ return mFormatData[static_cast<size_t>(formatID)];
}
-size_t TextureCapsMap::size() const
+void TextureCapsMap::set(angle::Format::ID formatID, const TextureCaps &caps)
{
- return mCapsMap.size();
+ get(formatID) = caps;
+}
+
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+ const Extensions &extensions,
+ TextureCapsMap *capsMap)
+{
+ for (GLenum internalFormat : GetAllSizedInternalFormats())
+ {
+ capsMap->insert(internalFormat,
+ GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
+ }
}
Extensions::Extensions()
@@ -111,23 +158,25 @@ Extensions::Extensions()
textureCompressionDXT1(false),
textureCompressionDXT3(false),
textureCompressionDXT5(false),
+ textureCompressionS3TCsRGB(false),
textureCompressionASTCHDR(false),
textureCompressionASTCLDR(false),
compressedETC1RGB8Texture(false),
+ sRGB(false),
depthTextures(false),
depth32(false),
textureStorage(false),
textureNPOT(false),
drawBuffers(false),
textureFilterAnisotropic(false),
- maxTextureAnisotropy(false),
+ maxTextureAnisotropy(0.0f),
occlusionQueryBoolean(false),
fence(false),
- timerQuery(false),
disjointTimerQuery(false),
queryCounterBitsTimeElapsed(0),
queryCounterBitsTimestamp(0),
robustness(false),
+ robustBufferAccessBehavior(false),
blendMinMax(false),
framebufferBlit(false),
framebufferMultisample(false),
@@ -135,10 +184,9 @@ Extensions::Extensions()
packReverseRowOrder(false),
standardDerivatives(false),
shaderTextureLOD(false),
- shaderFramebufferFetch(false),
- ARMshaderFramebufferFetch(false),
- NVshaderFramebufferFetch(false),
fragDepth(false),
+ multiview(false),
+ maxViews(1u),
textureUsage(false),
translatedShaderSource(false),
fboRenderMipmap(false),
@@ -147,6 +195,7 @@ Extensions::Extensions()
eglImage(false),
eglImageExternal(false),
eglImageExternalEssl3(false),
+ eglStreamConsumerExternal(false),
unpackSubimage(false),
packSubimage(false),
vertexArrayObject(false),
@@ -157,7 +206,31 @@ Extensions::Extensions()
maxLabelLength(0),
noError(false),
lossyETCDecode(false),
- colorBufferFloat(false)
+ bindUniformLocation(false),
+ syncQuery(false),
+ copyTexture(false),
+ copyCompressedTexture(false),
+ webglCompatibility(false),
+ requestExtension(false),
+ bindGeneratesResource(false),
+ robustClientMemory(false),
+ textureSRGBDecode(false),
+ sRGBWriteControl(false),
+ colorBufferFloatRGB(false),
+ colorBufferFloatRGBA(false),
+ colorBufferFloat(false),
+ multisampleCompatibility(false),
+ framebufferMixedSamples(false),
+ textureNorm16(false),
+ pathRendering(false),
+ surfacelessContext(false),
+ clientArrays(false),
+ robustResourceInitialization(false),
+ programCacheControl(false),
+ textureRectangle(false),
+ geometryShader(false),
+ maxGeometryOutputVertices(0),
+ maxGeometryShaderInvocations(0)
{
}
@@ -165,70 +238,13 @@ std::vector<std::string> Extensions::getStrings() const
{
std::vector<std::string> extensionStrings;
- // clang-format off
- // | Extension name | Supported flag | Output vector |
- InsertExtensionString("GL_OES_element_index_uint", elementIndexUint, &extensionStrings);
- InsertExtensionString("GL_OES_packed_depth_stencil", packedDepthStencil, &extensionStrings);
- InsertExtensionString("GL_OES_get_program_binary", getProgramBinary, &extensionStrings);
- InsertExtensionString("GL_OES_rgb8_rgba8", rgb8rgba8, &extensionStrings);
- InsertExtensionString("GL_EXT_texture_format_BGRA8888", textureFormatBGRA8888, &extensionStrings);
- InsertExtensionString("GL_EXT_read_format_bgra", readFormatBGRA, &extensionStrings);
- InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings);
- InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings);
- InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings);
- InsertExtensionString("GL_EXT_color_buffer_half_float", colorBufferHalfFloat, &extensionStrings);
- InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings);
- InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings);
- InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings);
- InsertExtensionString("GL_OES_texture_float_linear", textureFloatLinear, &extensionStrings);
- InsertExtensionString("GL_EXT_texture_rg", textureRG, &extensionStrings);
- InsertExtensionString("GL_EXT_texture_compression_dxt1", textureCompressionDXT1, &extensionStrings);
- InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3, &extensionStrings);
- InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5, &extensionStrings);
- InsertExtensionString("GL_KHR_texture_compression_astc_hdr", textureCompressionASTCHDR, &extensionStrings);
- InsertExtensionString("GL_KHR_texture_compression_astc_ldr", textureCompressionASTCLDR, &extensionStrings);
- InsertExtensionString("GL_OES_compressed_ETC1_RGB8_texture", compressedETC1RGB8Texture, &extensionStrings);
- InsertExtensionString("GL_EXT_sRGB", sRGB, &extensionStrings);
- InsertExtensionString("GL_ANGLE_depth_texture", depthTextures, &extensionStrings);
- InsertExtensionString("GL_OES_depth32", depth32, &extensionStrings);
- InsertExtensionString("GL_EXT_texture_storage", textureStorage, &extensionStrings);
- InsertExtensionString("GL_OES_texture_npot", textureNPOT, &extensionStrings);
- InsertExtensionString("GL_EXT_draw_buffers", drawBuffers, &extensionStrings);
- InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings);
- InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings);
- InsertExtensionString("GL_NV_fence", fence, &extensionStrings);
- InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings);
- InsertExtensionString("GL_EXT_disjoint_timer_query", disjointTimerQuery, &extensionStrings);
- InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings);
- InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings);
- InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings);
- InsertExtensionString("GL_ANGLE_framebuffer_multisample", framebufferMultisample, &extensionStrings);
- InsertExtensionString("GL_ANGLE_instanced_arrays", instancedArrays, &extensionStrings);
- InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings);
- InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings);
- InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings);
- InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings);
- InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch, &extensionStrings);
- InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings);
- InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings);
- InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings);
- InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings);
- InsertExtensionString("GL_OES_fbo_render_mipmap", fboRenderMipmap, &extensionStrings);
- InsertExtensionString("GL_EXT_discard_framebuffer", discardFramebuffer, &extensionStrings);
- InsertExtensionString("GL_EXT_debug_marker", debugMarker, &extensionStrings);
- InsertExtensionString("GL_OES_EGL_image", eglImage, &extensionStrings);
- InsertExtensionString("GL_OES_EGL_image_external", eglImageExternal, &extensionStrings);
- InsertExtensionString("GL_OES_EGL_image_external_essl3", eglImageExternalEssl3, &extensionStrings);
- InsertExtensionString("GL_EXT_unpack_subimage", unpackSubimage, &extensionStrings);
- InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings);
- InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings);
- InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings);
- InsertExtensionString("GL_KHR_debug", debug, &extensionStrings);
- // TODO(jmadill): Enable this when complete.
- //InsertExtensionString("GL_KHR_no_error", noError, &extensionStrings);
-
- InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings);
- // clang-format on
+ for (const auto &extensionInfo : GetExtensionInfoMap())
+ {
+ if (this->*(extensionInfo.second.ExtensionsMember))
+ {
+ extensionStrings.push_back(extensionInfo.first);
+ }
+ }
return extensionStrings;
}
@@ -243,10 +259,14 @@ Limitations::Limitations()
{
}
-static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector<GLenum> &requiredFormats,
- bool requiresTexturing, bool requiresFiltering, bool requiresRendering)
+static bool GetFormatSupportBase(const TextureCapsMap &textureCaps,
+ const GLenum *requiredFormats,
+ size_t requiredFormatsSize,
+ bool requiresTexturing,
+ bool requiresFiltering,
+ bool requiresRendering)
{
- for (size_t i = 0; i < requiredFormats.size(); i++)
+ for (size_t i = 0; i < requiredFormatsSize; i++)
{
const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
@@ -269,11 +289,23 @@ static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vecto
return true;
}
+template <size_t N>
+static bool GetFormatSupport(const TextureCapsMap &textureCaps,
+ const GLenum (&requiredFormats)[N],
+ bool requiresTexturing,
+ bool requiresFiltering,
+ bool requiresRendering)
+{
+ return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing,
+ requiresFiltering, requiresRendering);
+}
+
// Check for GL_OES_packed_depth_stencil
static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_DEPTH24_STENCIL8);
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH24_STENCIL8,
+ };
return GetFormatSupport(textureCaps, requiredFormats, false, false, true);
}
@@ -281,9 +313,9 @@ static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps
// Checks for GL_OES_rgb8_rgba8 support
static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGB8);
- requiredFormats.push_back(GL_RGBA8);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB8, GL_RGBA8,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
@@ -291,8 +323,9 @@ static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCap
// Checks for GL_EXT_texture_format_BGRA8888 support
static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_BGRA8_EXT);
+ constexpr GLenum requiredFormats[] = {
+ GL_BGRA8_EXT,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
@@ -300,11 +333,9 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
// Checks for GL_OES_color_buffer_half_float support
static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGBA16F);
- requiredFormats.push_back(GL_RGB16F);
- requiredFormats.push_back(GL_RG16F);
- requiredFormats.push_back(GL_R16F);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
@@ -312,19 +343,19 @@ static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCa
// Checks for GL_OES_texture_half_float support
static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGB16F);
- requiredFormats.push_back(GL_RGBA16F);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB16F, GL_RGBA16F,
+ };
- return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, false);
}
// Checks for GL_OES_texture_half_float_linear support
static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGB16F);
- requiredFormats.push_back(GL_RGBA16F);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB16F, GL_RGBA16F,
+ };
return DetermineHalfFloatTextureSupport(textureCaps) &&
GetFormatSupport(textureCaps, requiredFormats, true, true, false);
@@ -333,50 +364,65 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text
// Checks for GL_OES_texture_float support
static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGB32F);
- requiredFormats.push_back(GL_RGBA32F);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB32F, GL_RGBA32F,
+ };
- return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, false);
}
// Checks for GL_OES_texture_float_linear support
static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_RGB32F);
- requiredFormats.push_back(GL_RGBA32F);
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB32F, GL_RGBA32F,
+ };
return DetermineFloatTextureSupport(textureCaps) &&
GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Checks for GL_EXT_texture_rg support
+static bool DetermineRGHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_R16F, GL_RG16F,
+ };
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
+}
+
+static bool DetermineRGFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_R32F, GL_RG32F,
+ };
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
+}
+
static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool checkHalfFloatFormats, bool checkFloatFormats)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_R8);
- requiredFormats.push_back(GL_RG8);
- if (checkHalfFloatFormats)
+ if (checkHalfFloatFormats && !DetermineRGHalfFloatTextureSupport(textureCaps))
{
- requiredFormats.push_back(GL_R16F);
- requiredFormats.push_back(GL_RG16F);
+ return false;
}
- if (checkFloatFormats)
+
+ if (checkFloatFormats && !DetermineRGFloatTextureSupport(textureCaps))
{
- requiredFormats.push_back(GL_R32F);
- requiredFormats.push_back(GL_RG32F);
+ return false;
}
+ constexpr GLenum requiredFormats[] = {
+ GL_R8, GL_RG8,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_EXT_texture_compression_dxt1
static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
@@ -384,8 +430,9 @@ static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_ANGLE_texture_compression_dxt3
static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
@@ -393,8 +440,20 @@ static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_ANGLE_texture_compression_dxt5
static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
+}
+
+// Check for GL_EXT_texture_compression_s3tc_srgb
+static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
@@ -402,35 +461,22 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_KHR_texture_compression_astc_hdr and GL_KHR_texture_compression_astc_ldr
static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_4x4_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x4_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x8_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x8_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x10_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x10_KHR);
- requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x12_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
- requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
+ GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
+ GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
@@ -438,8 +484,9 @@ static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_ETC1_RGB8_OES
static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_ETC1_RGB8_OES);
+ constexpr GLenum requiredFormats[] = {
+ GL_ETC1_RGB8_OES,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
@@ -447,12 +494,13 @@ static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_ANGLE_texture_compression_dxt5
static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFilterFormats;
- requiredFilterFormats.push_back(GL_SRGB8);
- requiredFilterFormats.push_back(GL_SRGB8_ALPHA8);
+ constexpr GLenum requiredFilterFormats[] = {
+ GL_SRGB8, GL_SRGB8_ALPHA8,
+ };
- std::vector<GLenum> requiredRenderFormats;
- requiredRenderFormats.push_back(GL_SRGB8_ALPHA8);
+ constexpr GLenum requiredRenderFormats[] = {
+ GL_SRGB8_ALPHA8,
+ };
return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
@@ -461,10 +509,9 @@ static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_ANGLE_depth_texture
static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_DEPTH_COMPONENT16);
- requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES);
- requiredFormats.push_back(GL_DEPTH24_STENCIL8_OES);
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32_OES, GL_DEPTH24_STENCIL8_OES,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
@@ -472,27 +519,59 @@ static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
// Check for GL_OES_depth32
static bool DetermineDepth32Support(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES);
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT32_OES,
+ };
return GetFormatSupport(textureCaps, requiredFormats, false, false, true);
}
+// Check for GL_CHROMIUM_color_buffer_float_rgb
+static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB32F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
+}
+
+// Check for GL_CHROMIUM_color_buffer_float_rgba
+static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA32F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
+}
+
// Check for GL_EXT_color_buffer_float
static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
{
- std::vector<GLenum> requiredFormats;
- requiredFormats.push_back(GL_R16F);
- requiredFormats.push_back(GL_RG16F);
- requiredFormats.push_back(GL_RGBA16F);
- requiredFormats.push_back(GL_R32F);
- requiredFormats.push_back(GL_RG32F);
- requiredFormats.push_back(GL_RGBA32F);
- requiredFormats.push_back(GL_R11F_G11F_B10F);
+ constexpr GLenum requiredFormats[] = {
+ GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_RGBA32F, GL_R11F_G11F_B10F,
+ };
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
+// Check for GL_EXT_texture_norm16
+static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFilterFormats[] = {
+ GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
+ GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT,
+ };
+
+ constexpr GLenum requiredRenderFormats[] = {
+ GL_R16_EXT, GL_RG16_EXT, GL_RGBA16_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
+ GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
+}
+
void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
{
packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps);
@@ -507,47 +586,161 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
+ textureCompressionS3TCsRGB = DetermineS3TCsRGBTextureSupport(textureCaps);
textureCompressionASTCHDR = DetermineASTCTextureSupport(textureCaps);
textureCompressionASTCLDR = textureCompressionASTCHDR;
compressedETC1RGB8Texture = DetermineETC1RGB8TextureSupport(textureCaps);
sRGB = DetermineSRGBTextureSupport(textureCaps);
depthTextures = DetermineDepthTextureSupport(textureCaps);
depth32 = DetermineDepth32Support(textureCaps);
+ colorBufferFloatRGB = DetermineColorBufferFloatRGBSupport(textureCaps);
+ colorBufferFloatRGBA = DetermineColorBufferFloatRGBASupport(textureCaps);
colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
+ textureNorm16 = DetermineTextureNorm16Support(textureCaps);
}
-TypePrecision::TypePrecision()
+const ExtensionInfoMap &GetExtensionInfoMap()
{
- range[0] = 0;
- range[1] = 0;
- precision = 0;
+ auto buildExtensionInfoMap = []() {
+ auto enableableExtension = [](ExtensionInfo::ExtensionBool member) {
+ ExtensionInfo info;
+ info.Requestable = true;
+ info.ExtensionsMember = member;
+ return info;
+ };
+
+ auto esOnlyExtension = [](ExtensionInfo::ExtensionBool member) {
+ ExtensionInfo info;
+ info.ExtensionsMember = member;
+ return info;
+ };
+
+ // clang-format off
+ ExtensionInfoMap map;
+ map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUint);
+ map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencil);
+ map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinary);
+ map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8);
+ map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888);
+ map["GL_EXT_read_format_bgra"] = esOnlyExtension(&Extensions::readFormatBGRA);
+ map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObject);
+ map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapBuffer);
+ map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRange);
+ map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloat);
+ map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloat);
+ map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinear);
+ map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloat);
+ map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinear);
+ map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRG);
+ map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDXT1);
+ map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDXT3);
+ map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDXT5);
+ map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3TCsRGB);
+ map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionASTCHDR);
+ map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionASTCLDR);
+ map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8Texture);
+ map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGB);
+ map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextures);
+ map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32);
+ map["GL_EXT_texture_storage"] = esOnlyExtension(&Extensions::textureStorage);
+ map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNPOT);
+ map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffers);
+ map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropic);
+ map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBoolean);
+ map["GL_NV_fence"] = esOnlyExtension(&Extensions::fence);
+ map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQuery);
+ map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness);
+ map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehavior);
+ map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinMax);
+ map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlit);
+ map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample);
+ map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArrays);
+ map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder);
+ map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivatives);
+ map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD);
+ map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
+ map["GL_ANGLE_multiview"] = enableableExtension(&Extensions::multiview);
+ map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsage);
+ map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource);
+ map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmap);
+ map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer);
+ map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker);
+ map["GL_OES_EGL_image"] = esOnlyExtension(&Extensions::eglImage);
+ map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal);
+ map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3);
+ map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal);
+ map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
+ map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
+ map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
+ map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject);
+ map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
+ // TODO(jmadill): Enable this when complete.
+ //map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError);
+ map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyETCDecode);
+ map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation);
+ map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQuery);
+ map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
+ map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture);
+ map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
+ map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtension);
+ map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
+ map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
+ map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecode);
+ map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControl);
+ map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRGB);
+ map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRGBA);
+ map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility);
+ map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples);
+ map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16);
+ map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering);
+ map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext);
+ map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
+ map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
+ map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl);
+ map["GL_ANGLE_texture_rectangle"] = enableableExtension(&Extensions::textureRectangle);
+ map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShader);
+ // clang-format on
+
+ return map;
+ };
+
+ static const ExtensionInfoMap extensionInfo = buildExtensionInfoMap();
+ return extensionInfo;
}
+TypePrecision::TypePrecision() : range({{0, 0}}), precision(0)
+{
+}
+
+TypePrecision::TypePrecision(const TypePrecision &other) = default;
+
void TypePrecision::setIEEEFloat()
{
- range[0] = 127;
- range[1] = 127;
+ range = {{127, 127}};
precision = 23;
}
void TypePrecision::setTwosComplementInt(unsigned int bits)
{
- range[0] = GLint(bits) - 1;
- range[1] = GLint(bits) - 2;
+ range = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}};
precision = 0;
}
+void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p)
+{
+ range = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
+ precision = static_cast<GLint>(p);
+}
+
void TypePrecision::setSimulatedInt(unsigned int r)
{
- range[0] = GLint(r);
- range[1] = GLint(r);
+ range = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
precision = 0;
}
void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
{
- returnRange[0] = range[0];
- returnRange[1] = range[1];
+ std::copy(range.begin(), range.end(), returnRange);
*returnPrecision = precision;
}
@@ -555,37 +748,77 @@ Caps::Caps()
: maxElementIndex(0),
max3DTextureSize(0),
max2DTextureSize(0),
+ maxRectangleTextureSize(0),
maxArrayTextureLayers(0),
maxLODBias(0),
maxCubeMapTextureSize(0),
maxRenderbufferSize(0),
+ minAliasedPointSize(0),
+ maxAliasedPointSize(0),
+ minAliasedLineWidth(0),
+ maxAliasedLineWidth(0),
+
+ // Table 20.40
maxDrawBuffers(0),
+ maxFramebufferWidth(0),
+ maxFramebufferHeight(0),
+ maxFramebufferSamples(0),
maxColorAttachments(0),
maxViewportWidth(0),
maxViewportHeight(0),
- minAliasedPointSize(0),
- maxAliasedPointSize(0),
- minAliasedLineWidth(0),
- // Table 6.29
+ maxSampleMaskWords(0),
+ maxColorTextureSamples(0),
+ maxDepthTextureSamples(0),
+ maxIntegerSamples(0),
+ maxServerWaitTimeout(0),
+
+ // Table 20.41
+ maxVertexAttribRelativeOffset(0),
+ maxVertexAttribBindings(0),
+ maxVertexAttribStride(0),
maxElementsIndices(0),
maxElementsVertices(0),
- maxServerWaitTimeout(0),
- // Table 6.31
+
+ // Table 20.43
maxVertexAttributes(0),
maxVertexUniformComponents(0),
maxVertexUniformVectors(0),
maxVertexUniformBlocks(0),
maxVertexOutputComponents(0),
maxVertexTextureImageUnits(0),
- // Table 6.32
+ maxVertexAtomicCounterBuffers(0),
+ maxVertexAtomicCounters(0),
+ maxVertexImageUniforms(0),
+ maxVertexShaderStorageBlocks(0),
+
+ // Table 20.44
maxFragmentUniformComponents(0),
maxFragmentUniformVectors(0),
maxFragmentUniformBlocks(0),
maxFragmentInputComponents(0),
maxTextureImageUnits(0),
+ maxFragmentAtomicCounterBuffers(0),
+ maxFragmentAtomicCounters(0),
+ maxFragmentImageUniforms(0),
+ maxFragmentShaderStorageBlocks(0),
+ minProgramTextureGatherOffset(0),
+ maxProgramTextureGatherOffset(0),
minProgramTexelOffset(0),
maxProgramTexelOffset(0),
- // Table 6.33
+
+ // Table 20.45
+ maxComputeWorkGroupInvocations(0),
+ maxComputeUniformBlocks(0),
+ maxComputeTextureImageUnits(0),
+ maxComputeSharedMemorySize(0),
+ maxComputeUniformComponents(0),
+ maxComputeAtomicCounterBuffers(0),
+ maxComputeAtomicCounters(0),
+ maxComputeImageUniforms(0),
+ maxCombinedComputeUniformComponents(0),
+ maxComputeShaderStorageBlocks(0),
+
+ // Table 20.46
maxUniformBufferBindings(0),
maxUniformBlockSize(0),
uniformBufferOffsetAlignment(0),
@@ -595,15 +828,233 @@ Caps::Caps()
maxVaryingComponents(0),
maxVaryingVectors(0),
maxCombinedTextureImageUnits(0),
- // Table 6.34
+ maxCombinedShaderOutputResources(0),
+
+ // Table 20.47
+ maxUniformLocations(0),
+ maxAtomicCounterBufferBindings(0),
+ maxAtomicCounterBufferSize(0),
+ maxCombinedAtomicCounterBuffers(0),
+ maxCombinedAtomicCounters(0),
+ maxImageUnits(0),
+ maxCombinedImageUniforms(0),
+ maxShaderStorageBufferBindings(0),
+ maxShaderStorageBlockSize(0),
+ maxCombinedShaderStorageBlocks(0),
+ shaderStorageBufferOffsetAlignment(0),
+
+ // Table 20.48
maxTransformFeedbackInterleavedComponents(0),
maxTransformFeedbackSeparateAttributes(0),
maxTransformFeedbackSeparateComponents(0),
- // Table 6.35
+
+ // Table 20.49
maxSamples(0)
{
+ for (size_t i = 0; i < 3; ++i)
+ {
+ maxComputeWorkGroupCount[i] = 0;
+ maxComputeWorkGroupSize[i] = 0;
+ }
}
+Caps::Caps(const Caps &other) = default;
+Caps::~Caps() = default;
+
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
+{
+ Caps caps;
+
+ if (clientVersion >= Version(2, 0))
+ {
+ // Table 6.18
+ caps.max2DTextureSize = 64;
+ caps.maxCubeMapTextureSize = 16;
+ caps.maxViewportWidth = caps.max2DTextureSize;
+ caps.maxViewportHeight = caps.max2DTextureSize;
+ caps.minAliasedPointSize = 1;
+ caps.maxAliasedPointSize = 1;
+ caps.minAliasedLineWidth = 1;
+ caps.maxAliasedLineWidth = 1;
+
+ // Table 6.19
+ caps.vertexHighpFloat.setSimulatedFloat(62, 16);
+ caps.vertexMediumpFloat.setSimulatedFloat(14, 10);
+ caps.vertexLowpFloat.setSimulatedFloat(1, 8);
+ caps.vertexHighpInt.setSimulatedInt(16);
+ caps.vertexMediumpInt.setSimulatedInt(10);
+ caps.vertexLowpInt.setSimulatedInt(8);
+ caps.fragmentHighpFloat.setSimulatedFloat(62, 16);
+ caps.fragmentMediumpFloat.setSimulatedFloat(14, 10);
+ caps.fragmentLowpFloat.setSimulatedFloat(1, 8);
+ caps.fragmentHighpInt.setSimulatedInt(16);
+ caps.fragmentMediumpInt.setSimulatedInt(10);
+ caps.fragmentLowpInt.setSimulatedInt(8);
+
+ // Table 6.20
+ caps.maxVertexAttributes = 8;
+ caps.maxVertexUniformVectors = 128;
+ caps.maxVaryingVectors = 8;
+ caps.maxCombinedTextureImageUnits = 8;
+ caps.maxTextureImageUnits = 8;
+ caps.maxFragmentUniformVectors = 16;
+ caps.maxRenderbufferSize = 1;
+ }
+
+ if (clientVersion >= Version(3, 0))
+ {
+ // Table 6.28
+ caps.maxElementIndex = (1 << 24) - 1;
+ caps.max3DTextureSize = 256;
+ caps.max2DTextureSize = 2048;
+ caps.maxArrayTextureLayers = 256;
+ caps.maxLODBias = 2.0f;
+ caps.maxCubeMapTextureSize = 2048;
+ caps.maxRenderbufferSize = 2048;
+ caps.maxDrawBuffers = 4;
+ caps.maxColorAttachments = 4;
+ caps.maxViewportWidth = caps.max2DTextureSize;
+ caps.maxViewportHeight = caps.max2DTextureSize;
+
+ // Table 6.29
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
+ caps.vertexHighpFloat.setIEEEFloat();
+ caps.vertexHighpInt.setTwosComplementInt(32);
+ caps.vertexMediumpInt.setTwosComplementInt(16);
+ caps.vertexLowpInt.setTwosComplementInt(8);
+ caps.fragmentHighpFloat.setIEEEFloat();
+ caps.fragmentHighpInt.setSimulatedInt(32);
+ caps.fragmentMediumpInt.setTwosComplementInt(16);
+ caps.fragmentLowpInt.setTwosComplementInt(8);
+ caps.maxServerWaitTimeout = 0;
+
+ // Table 6.31
+ caps.maxVertexAttributes = 16;
+ caps.maxVertexUniformComponents = 1024;
+ caps.maxVertexUniformVectors = 256;
+ caps.maxVertexUniformBlocks = 12;
+ caps.maxVertexOutputComponents = 64;
+ caps.maxVertexTextureImageUnits = 16;
+
+ // Table 6.32
+ caps.maxFragmentUniformComponents = 896;
+ caps.maxFragmentUniformVectors = 224;
+ caps.maxFragmentUniformBlocks = 12;
+ caps.maxFragmentInputComponents = 60;
+ caps.maxTextureImageUnits = 16;
+ caps.minProgramTexelOffset = -8;
+ caps.maxProgramTexelOffset = 7;
+
+ // Table 6.33
+ caps.maxUniformBufferBindings = 24;
+ caps.maxUniformBlockSize = 16384;
+ caps.uniformBufferOffsetAlignment = 256;
+ caps.maxCombinedUniformBlocks = 24;
+ caps.maxCombinedVertexUniformComponents =
+ caps.maxVertexUniformBlocks * (caps.maxUniformBlockSize / 4) +
+ caps.maxVertexUniformComponents;
+ caps.maxCombinedFragmentUniformComponents =
+ caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) +
+ caps.maxFragmentUniformComponents;
+ caps.maxVaryingComponents = 60;
+ caps.maxVaryingVectors = 15;
+ caps.maxCombinedTextureImageUnits = 32;
+
+ // Table 6.34
+ caps.maxTransformFeedbackInterleavedComponents = 64;
+ caps.maxTransformFeedbackSeparateAttributes = 4;
+ caps.maxTransformFeedbackSeparateComponents = 4;
+
+ // Table 3.35
+ caps.maxSamples = 4;
+ }
+
+ if (clientVersion >= Version(3, 1))
+ {
+ // Table 20.40
+ caps.maxFramebufferWidth = 2048;
+ caps.maxFramebufferHeight = 2048;
+ caps.maxFramebufferSamples = 4;
+ caps.maxSampleMaskWords = 1;
+ caps.maxColorTextureSamples = 1;
+ caps.maxDepthTextureSamples = 1;
+ caps.maxIntegerSamples = 1;
+
+ // Table 20.41
+ caps.maxVertexAttribRelativeOffset = 2047;
+ caps.maxVertexAttribBindings = 16;
+ caps.maxVertexAttribStride = 2048;
+
+ // Table 20.43
+ caps.maxVertexAtomicCounterBuffers = 0;
+ caps.maxVertexAtomicCounters = 0;
+ caps.maxVertexImageUniforms = 0;
+ caps.maxVertexShaderStorageBlocks = 0;
+
+ // Table 20.44
+ caps.maxFragmentUniformComponents = 1024;
+ caps.maxFragmentUniformVectors = 256;
+ caps.maxFragmentAtomicCounterBuffers = 0;
+ caps.maxFragmentAtomicCounters = 0;
+ caps.maxFragmentImageUniforms = 0;
+ caps.maxFragmentShaderStorageBlocks = 0;
+ caps.minProgramTextureGatherOffset = 0;
+ caps.maxProgramTextureGatherOffset = 0;
+
+ // Table 20.45
+ caps.maxComputeWorkGroupCount = {{65535, 65535, 65535}};
+ caps.maxComputeWorkGroupSize = {{128, 128, 64}};
+ caps.maxComputeWorkGroupInvocations = 12;
+ caps.maxComputeUniformBlocks = 12;
+ caps.maxComputeTextureImageUnits = 16;
+ caps.maxComputeSharedMemorySize = 16384;
+ caps.maxComputeUniformComponents = 1024;
+ caps.maxComputeAtomicCounterBuffers = 1;
+ caps.maxComputeAtomicCounters = 8;
+ caps.maxComputeImageUniforms = 4;
+ caps.maxCombinedComputeUniformComponents =
+ caps.maxComputeUniformBlocks * static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
+ caps.maxComputeUniformComponents;
+ caps.maxComputeShaderStorageBlocks = 4;
+
+ // Table 20.46
+ caps.maxUniformBufferBindings = 36;
+ caps.maxCombinedFragmentUniformComponents =
+ caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) +
+ caps.maxFragmentUniformComponents;
+ caps.maxCombinedTextureImageUnits = 48;
+ caps.maxCombinedShaderOutputResources = 4;
+
+ // Table 20.47
+ caps.maxUniformLocations = 1024;
+ caps.maxAtomicCounterBufferBindings = 1;
+ caps.maxAtomicCounterBufferSize = 32;
+ caps.maxCombinedAtomicCounterBuffers = 1;
+ caps.maxCombinedAtomicCounters = 8;
+ caps.maxImageUnits = 4;
+ caps.maxCombinedImageUniforms = 4;
+ caps.maxShaderStorageBufferBindings = 4;
+ caps.maxShaderStorageBlockSize = 1 << 27;
+ caps.maxCombinedShaderStorageBlocks = 4;
+ caps.shaderStorageBufferOffsetAlignment = 256;
+ }
+
+ if (extensions.textureRectangle)
+ {
+ caps.maxRectangleTextureSize = 64;
+ }
+
+ return caps;
+}
}
namespace egl
@@ -617,6 +1068,7 @@ Caps::Caps()
DisplayExtensions::DisplayExtensions()
: createContextRobustness(false),
d3dShareHandleClientBuffer(false),
+ d3dTextureClientBuffer(false),
surfaceD3DTexture2DShareHandle(false),
querySurfacePointer(false),
windowFixedSize(false),
@@ -635,7 +1087,21 @@ DisplayExtensions::DisplayExtensions()
getAllProcAddresses(false),
flexibleSurfaceCompatibility(false),
directComposition(false),
- createContextNoError(false)
+ createContextNoError(false),
+ stream(false),
+ streamConsumerGLTexture(false),
+ streamConsumerGLTextureYUV(false),
+ streamProducerD3DTextureNV12(false),
+ createContextWebGLCompatibility(false),
+ createContextBindGeneratesResource(false),
+ getSyncValues(false),
+ swapBuffersWithDamage(false),
+ pixelFormatFloat(false),
+ surfacelessContext(false),
+ displayTextureShareGroup(false),
+ createContextClientArrays(false),
+ programCacheControl(false),
+ robustResourceInitialization(false)
{
}
@@ -644,29 +1110,44 @@ std::vector<std::string> DisplayExtensions::getStrings() const
std::vector<std::string> extensionStrings;
// clang-format off
- // | Extension name | Supported flag | Output vector |
- InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings);
- InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
- InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
- InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
- InsertExtensionString("EGL_KHR_image", image, &extensionStrings);
- InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings);
- InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings);
- InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings);
- InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings);
- InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings);
- InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings);
- InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings);
- InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings);
+ // | Extension name | Supported flag | Output vector |
+ InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings);
+ InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
+ InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
+ InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image", image, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings);
+ InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings);
+ InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings);
+ InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings);
+ InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings);
+ InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings);
+ InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings);
+ InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings);
+ InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12", streamProducerD3DTextureNV12, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings);
+ InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
+ InsertExtensionString("EGL_CHROMIUM_sync_control", getSyncValues, &extensionStrings);
+ InsertExtensionString("EGL_EXT_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings);
+ InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
+ InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControl, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitialization, &extensionStrings);
// TODO(jmadill): Enable this when complete.
- //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
+ //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on
return extensionStrings;
@@ -694,6 +1175,7 @@ ClientExtensions::ClientExtensions()
platformANGLE(false),
platformANGLED3D(false),
platformANGLEOpenGL(false),
+ platformANGLEVulkan(false),
deviceCreation(false),
deviceCreationD3D11(false),
x11Visual(false),
@@ -702,6 +1184,8 @@ ClientExtensions::ClientExtensions()
{
}
+ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
+
std::vector<std::string> ClientExtensions::getStrings() const
{
std::vector<std::string> extensionStrings;
@@ -714,6 +1198,8 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings);
InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings);
@@ -724,4 +1210,4 @@ std::vector<std::string> ClientExtensions::getStrings() const
return extensionStrings;
}
-}
+} // namespace egl
diff --git a/src/3rdparty/angle/src/libANGLE/Caps.h b/src/3rdparty/angle/src/libANGLE/Caps.h
index d0e839a2ba..64bdf97112 100644
--- a/src/3rdparty/angle/src/libANGLE/Caps.h
+++ b/src/3rdparty/angle/src/libANGLE/Caps.h
@@ -8,21 +8,28 @@
#define LIBANGLE_CAPS_H_
#include "angle_gl.h"
+#include "libANGLE/Version.h"
#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/Format.h"
#include <map>
#include <set>
#include <string>
#include <vector>
+#include <array>
namespace gl
{
+struct Extensions;
+
typedef std::set<GLuint> SupportedSampleSet;
struct TextureCaps
{
TextureCaps();
+ TextureCaps(const TextureCaps &other);
+ ~TextureCaps();
// Supports for basic texturing: glTexImage, glTexSubImage, etc
bool texturable;
@@ -44,26 +51,37 @@ struct TextureCaps
GLuint getNearestSamples(GLuint requestedSamples) const;
};
-class TextureCapsMap
+TextureCaps GenerateMinimumTextureCaps(GLenum internalFormat,
+ const Version &clientVersion,
+ const Extensions &extensions);
+
+class TextureCapsMap final : angle::NonCopyable
{
public:
- typedef std::map<GLenum, TextureCaps>::const_iterator const_iterator;
+ TextureCapsMap();
+ ~TextureCapsMap();
+ // These methods are deprecated. Please use angle::Format for new features.
void insert(GLenum internalFormat, const TextureCaps &caps);
- void remove(GLenum internalFormat);
-
const TextureCaps &get(GLenum internalFormat) const;
- const_iterator begin() const;
- const_iterator end() const;
+ void clear();
- size_t size() const;
+ // Prefer using angle::Format methods.
+ const TextureCaps &get(angle::Format::ID formatID) const;
+ void set(angle::Format::ID formatID, const TextureCaps &caps);
private:
- typedef std::map<GLenum, TextureCaps> InternalFormatToCapsMap;
- InternalFormatToCapsMap mCapsMap;
+ TextureCaps &get(angle::Format::ID formatID);
+
+ // Indexed by angle::Format::ID
+ std::array<TextureCaps, angle::kNumANGLEFormats> mFormatData;
};
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+ const Extensions &extensions,
+ TextureCapsMap *capsMap);
+
struct Extensions
{
Extensions();
@@ -87,6 +105,7 @@ struct Extensions
// GL_EXT_sRGB
// GL_ANGLE_depth_texture, GL_OES_depth32
// GL_EXT_color_buffer_float
+ // GL_EXT_texture_norm16
void setTextureExtensionSupport(const TextureCapsMap &textureCaps);
// ES2 Extension support
@@ -141,12 +160,18 @@ struct Extensions
bool textureRG;
// GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and GL_ANGLE_texture_compression_dxt5
- // Implies that TextureCaps for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+ // Implies that TextureCaps exist for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
// GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE and GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE
bool textureCompressionDXT1;
bool textureCompressionDXT3;
bool textureCompressionDXT5;
+ // GL_EXT_texture_compression_s3tc_srgb
+ // Implies that TextureCaps exist for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
+ // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, and
+ // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
+ bool textureCompressionS3TCsRGB;
+
// GL_KHR_texture_compression_astc_hdr
bool textureCompressionASTCHDR;
@@ -188,9 +213,6 @@ struct Extensions
// GL_NV_fence
bool fence;
- // GL_ANGLE_timer_query
- bool timerQuery;
-
// GL_EXT_disjoint_timer_query
bool disjointTimerQuery;
GLuint queryCounterBitsTimeElapsed;
@@ -199,6 +221,9 @@ struct Extensions
// GL_EXT_robustness
bool robustness;
+ // GL_KHR_robust_buffer_access_behavior
+ bool robustBufferAccessBehavior;
+
// GL_EXT_blend_minmax
bool blendMinMax;
@@ -220,18 +245,13 @@ struct Extensions
// GL_EXT_shader_texture_lod
bool shaderTextureLOD;
- // GL_EXT_shader_framebuffer_fetch
- bool shaderFramebufferFetch;
-
- // GL_ARM_shader_framebuffer_fetch
- bool ARMshaderFramebufferFetch;
-
- // GL_NV_shader_framebuffer_fetch
- bool NVshaderFramebufferFetch;
-
// GL_EXT_frag_depth
bool fragDepth;
+ // ANGLE_multiview
+ bool multiview;
+ GLuint maxViews;
+
// GL_ANGLE_texture_usage
bool textureUsage;
@@ -256,6 +276,9 @@ struct Extensions
// GL_OES_EGL_image_external_essl3
bool eglImageExternalEssl3;
+ // NV_EGL_stream_consumer_external
+ bool eglStreamConsumerExternal;
+
// EXT_unpack_subimage
bool unpackSubimage;
@@ -278,12 +301,98 @@ struct Extensions
// GL_ANGLE_lossy_etc_decode
bool lossyETCDecode;
+ // GL_CHROMIUM_bind_uniform_location
+ bool bindUniformLocation;
+
+ // GL_CHROMIUM_sync_query
+ bool syncQuery;
+
+ // GL_CHROMIUM_copy_texture
+ bool copyTexture;
+
+ // GL_CHROMIUM_copy_compressed_texture
+ bool copyCompressedTexture;
+
+ // GL_ANGLE_webgl_compatibility
+ bool webglCompatibility;
+
+ // GL_ANGLE_request_extension
+ bool requestExtension;
+
+ // GL_CHROMIUM_bind_generates_resource
+ bool bindGeneratesResource;
+
+ // GL_ANGLE_robust_client_memory
+ bool robustClientMemory;
+
+ // GL_EXT_texture_sRGB_decode
+ bool textureSRGBDecode;
+
+ // GL_EXT_sRGB_write_control
+ bool sRGBWriteControl;
+
+ // GL_CHROMIUM_color_buffer_float_rgb
+ bool colorBufferFloatRGB;
+
+ // GL_CHROMIUM_color_buffer_float_rgba
+ bool colorBufferFloatRGBA;
+
// ES3 Extension support
// GL_EXT_color_buffer_float
bool colorBufferFloat;
+
+ // GL_EXT_multisample_compatibility.
+ // written against ES 3.1 but can apply to earlier versions.
+ bool multisampleCompatibility;
+
+ // GL_CHROMIUM_framebuffer_mixed_samples
+ bool framebufferMixedSamples;
+
+ // GL_EXT_texture_norm16
+ // written against ES 3.1 but can apply to ES 3.0 as well.
+ bool textureNorm16;
+
+ // GL_CHROMIUM_path_rendering
+ bool pathRendering;
+
+ // GL_OES_surfaceless_context
+ bool surfacelessContext;
+
+ // GL_ANGLE_client_arrays
+ bool clientArrays;
+
+ // GL_ANGLE_robust_resource_initialization
+ bool robustResourceInitialization;
+
+ // GL_ANGLE_program_cache_control
+ bool programCacheControl;
+
+ // GL_ANGLE_texture_rectangle
+ bool textureRectangle;
+
+ // GL_EXT_geometry_shader
+ bool geometryShader;
+ // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader
+ // limits
+ // TODO(jiawei.shao@intel.com): add all implementation dependent geometry shader limits.
+ GLuint maxGeometryOutputVertices;
+ GLuint maxGeometryShaderInvocations;
};
+struct ExtensionInfo
+{
+ // If this extension can be enabled with glRequestExtension (GL_ANGLE_request_extension)
+ bool Requestable = false;
+
+ // Pointer to a boolean member of the Extensions struct
+ typedef bool(Extensions::*ExtensionBool);
+ ExtensionBool ExtensionsMember = nullptr;
+};
+
+using ExtensionInfoMap = std::map<std::string, ExtensionInfo>;
+const ExtensionInfoMap &GetExtensionInfoMap();
+
struct Limitations
{
Limitations();
@@ -311,39 +420,57 @@ struct Limitations
struct TypePrecision
{
TypePrecision();
+ TypePrecision(const TypePrecision &other);
void setIEEEFloat();
void setTwosComplementInt(unsigned int bits);
+ void setSimulatedFloat(unsigned int range, unsigned int precision);
void setSimulatedInt(unsigned int range);
void get(GLint *returnRange, GLint *returnPrecision) const;
- GLint range[2];
+ std::array<GLint, 2> range;
GLint precision;
};
struct Caps
{
Caps();
+ Caps(const Caps &other);
+ ~Caps();
- // Table 6.28, implementation dependent values
+ // ES 3.1 (April 29, 2015) 20.39: implementation dependent values
GLuint64 maxElementIndex;
GLuint max3DTextureSize;
GLuint max2DTextureSize;
+ GLuint maxRectangleTextureSize;
GLuint maxArrayTextureLayers;
GLfloat maxLODBias;
GLuint maxCubeMapTextureSize;
GLuint maxRenderbufferSize;
- GLuint maxDrawBuffers;
- GLuint maxColorAttachments;
- GLuint maxViewportWidth;
- GLuint maxViewportHeight;
GLfloat minAliasedPointSize;
GLfloat maxAliasedPointSize;
GLfloat minAliasedLineWidth;
GLfloat maxAliasedLineWidth;
- // Table 6.29, implementation dependent values (cont.)
+ // ES 3.1 (April 29, 2015) 20.40: implementation dependent values (cont.)
+ GLuint maxDrawBuffers;
+ GLuint maxFramebufferWidth;
+ GLuint maxFramebufferHeight;
+ GLuint maxFramebufferSamples;
+ GLuint maxColorAttachments;
+ GLuint maxViewportWidth;
+ GLuint maxViewportHeight;
+ GLuint maxSampleMaskWords;
+ GLuint maxColorTextureSamples;
+ GLuint maxDepthTextureSamples;
+ GLuint maxIntegerSamples;
+ GLuint64 maxServerWaitTimeout;
+
+ // ES 3.1 (April 29, 2015) Table 20.41: Implementation dependent values (cont.)
+ GLint maxVertexAttribRelativeOffset;
+ GLuint maxVertexAttribBindings;
+ GLint maxVertexAttribStride;
GLuint maxElementsIndices;
GLuint maxElementsVertices;
std::vector<GLenum> compressedTextureFormats;
@@ -361,26 +488,49 @@ struct Caps
TypePrecision fragmentHighpInt;
TypePrecision fragmentMediumpInt;
TypePrecision fragmentLowpInt;
- GLuint64 maxServerWaitTimeout;
- // Table 6.31, implementation dependent vertex shader limits
+ // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits
GLuint maxVertexAttributes;
GLuint maxVertexUniformComponents;
GLuint maxVertexUniformVectors;
GLuint maxVertexUniformBlocks;
GLuint maxVertexOutputComponents;
GLuint maxVertexTextureImageUnits;
+ GLuint maxVertexAtomicCounterBuffers;
+ GLuint maxVertexAtomicCounters;
+ GLuint maxVertexImageUniforms;
+ GLuint maxVertexShaderStorageBlocks;
- // Table 6.32, implementation dependent fragment shader limits
+ // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits
GLuint maxFragmentUniformComponents;
GLuint maxFragmentUniformVectors;
GLuint maxFragmentUniformBlocks;
GLuint maxFragmentInputComponents;
GLuint maxTextureImageUnits;
+ GLuint maxFragmentAtomicCounterBuffers;
+ GLuint maxFragmentAtomicCounters;
+ GLuint maxFragmentImageUniforms;
+ GLuint maxFragmentShaderStorageBlocks;
+ GLint minProgramTextureGatherOffset;
+ GLuint maxProgramTextureGatherOffset;
GLint minProgramTexelOffset;
GLint maxProgramTexelOffset;
- // Table 6.33, implementation dependent aggregate shader limits
+ // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits
+ std::array<GLuint, 3> maxComputeWorkGroupCount;
+ std::array<GLuint, 3> maxComputeWorkGroupSize;
+ GLuint maxComputeWorkGroupInvocations;
+ GLuint maxComputeUniformBlocks;
+ GLuint maxComputeTextureImageUnits;
+ GLuint maxComputeSharedMemorySize;
+ GLuint maxComputeUniformComponents;
+ GLuint maxComputeAtomicCounterBuffers;
+ GLuint maxComputeAtomicCounters;
+ GLuint maxComputeImageUniforms;
+ GLuint maxCombinedComputeUniformComponents;
+ GLuint maxComputeShaderStorageBlocks;
+
+ // ES 3.1 (April 29, 2015) Table 20.46: implementation dependent aggregate shader limits
GLuint maxUniformBufferBindings;
GLuint64 maxUniformBlockSize;
GLuint uniformBufferOffsetAlignment;
@@ -390,16 +540,31 @@ struct Caps
GLuint maxVaryingComponents;
GLuint maxVaryingVectors;
GLuint maxCombinedTextureImageUnits;
-
- // Table 6.34, implementation dependent transform feedback limits
+ GLuint maxCombinedShaderOutputResources;
+
+ // ES 3.1 (April 29, 2015) Table 20.47: implementation dependent aggregate shader limits (cont.)
+ GLuint maxUniformLocations;
+ GLuint maxAtomicCounterBufferBindings;
+ GLuint maxAtomicCounterBufferSize;
+ GLuint maxCombinedAtomicCounterBuffers;
+ GLuint maxCombinedAtomicCounters;
+ GLuint maxImageUnits;
+ GLuint maxCombinedImageUniforms;
+ GLuint maxShaderStorageBufferBindings;
+ GLuint64 maxShaderStorageBlockSize;
+ GLuint maxCombinedShaderStorageBlocks;
+ GLuint shaderStorageBufferOffsetAlignment;
+
+ // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits
GLuint maxTransformFeedbackInterleavedComponents;
GLuint maxTransformFeedbackSeparateAttributes;
GLuint maxTransformFeedbackSeparateComponents;
- // Table 6.35, Framebuffer Dependent Values
+ // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values
GLuint maxSamples;
};
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions);
}
namespace egl
@@ -426,6 +591,9 @@ struct DisplayExtensions
// EGL_ANGLE_d3d_share_handle_client_buffer
bool d3dShareHandleClientBuffer;
+ // EGL_ANGLE_d3d_texture_client_buffer
+ bool d3dTextureClientBuffer;
+
// EGL_ANGLE_surface_d3d_texture_2d_share_handle
bool surfaceD3DTexture2DShareHandle;
@@ -482,6 +650,48 @@ struct DisplayExtensions
// KHR_create_context_no_error
bool createContextNoError;
+
+ // EGL_KHR_stream
+ bool stream;
+
+ // EGL_KHR_stream_consumer_gltexture
+ bool streamConsumerGLTexture;
+
+ // EGL_NV_stream_consumer_gltexture_yuv
+ bool streamConsumerGLTextureYUV;
+
+ // EGL_ANGLE_stream_producer_d3d_texture_nv12
+ bool streamProducerD3DTextureNV12;
+
+ // EGL_ANGLE_create_context_webgl_compatibility
+ bool createContextWebGLCompatibility;
+
+ // EGL_CHROMIUM_create_context_bind_generates_resource
+ bool createContextBindGeneratesResource;
+
+ // EGL_CHROMIUM_get_sync_values
+ bool getSyncValues;
+
+ // EGL_EXT_swap_buffers_with_damage
+ bool swapBuffersWithDamage;
+
+ // EGL_EXT_pixel_format_float
+ bool pixelFormatFloat;
+
+ // EGL_KHR_surfaceless_context
+ bool surfacelessContext;
+
+ // EGL_ANGLE_display_texture_share_group
+ bool displayTextureShareGroup;
+
+ // EGL_ANGLE_create_context_client_arrays
+ bool createContextClientArrays;
+
+ // EGL_ANGLE_program_cache_control
+ bool programCacheControl;
+
+ // EGL_ANGLE_robust_resource_initialization
+ bool robustResourceInitialization;
};
struct DeviceExtensions
@@ -498,6 +708,7 @@ struct DeviceExtensions
struct ClientExtensions
{
ClientExtensions();
+ ClientExtensions(const ClientExtensions &other);
// Generate a vector of supported extension strings
std::vector<std::string> getStrings() const;
@@ -520,6 +731,12 @@ struct ClientExtensions
// EGL_ANGLE_platform_angle_opengl
bool platformANGLEOpenGL;
+ // EGL_ANGLE_platform_angle_null
+ bool platformANGLENULL;
+
+ // EGL_ANGLE_platform_angle_vulkan
+ bool platformANGLEVulkan;
+
// EGL_ANGLE_device_creation
bool deviceCreation;
@@ -536,6 +753,6 @@ struct ClientExtensions
bool clientGetAllProcAddresses;
};
-}
+} // namespace egl
#endif // LIBANGLE_CAPS_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.cpp b/src/3rdparty/angle/src/libANGLE/Compiler.cpp
index 348c41bef3..236c7e1fc2 100644
--- a/src/3rdparty/angle/src/libANGLE/Compiler.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Compiler.cpp
@@ -9,9 +9,9 @@
#include "libANGLE/Compiler.h"
#include "common/debug.h"
-#include "libANGLE/Data.h"
+#include "libANGLE/ContextState.h"
#include "libANGLE/renderer/CompilerImpl.h"
-#include "libANGLE/renderer/ImplFactory.h"
+#include "libANGLE/renderer/GLImplFactory.h"
namespace gl
{
@@ -19,26 +19,46 @@ namespace gl
namespace
{
-// Global count of active shader compiler handles. Needed to know when to call ShInitialize and
-// ShFinalize.
+// Global count of active shader compiler handles. Needed to know when to call sh::Initialize and
+// sh::Finalize.
size_t activeCompilerHandles = 0;
+ShShaderSpec SelectShaderSpec(GLint majorVersion, GLint minorVersion, bool isWebGL)
+{
+ if (majorVersion >= 3)
+ {
+ if (minorVersion == 1)
+ {
+ return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
+ }
+ else
+ {
+ return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
+ }
+ }
+ return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
+}
+
} // anonymous namespace
-Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data)
+Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
: mImplementation(implFactory->createCompiler()),
- mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC),
+ mSpec(SelectShaderSpec(state.getClientMajorVersion(),
+ state.getClientMinorVersion(),
+ state.getExtensions().webglCompatibility)),
mOutputType(mImplementation->getTranslatorOutputType()),
mResources(),
mFragmentCompiler(nullptr),
- mVertexCompiler(nullptr)
+ mVertexCompiler(nullptr),
+ mComputeCompiler(nullptr),
+ mGeometryCompiler(nullptr)
{
- ASSERT(data.clientVersion == 2 || data.clientVersion == 3);
+ ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3);
- const gl::Caps &caps = *data.caps;
- const gl::Extensions &extensions = *data.extensions;
+ const gl::Caps &caps = state.getCaps();
+ const gl::Extensions &extensions = state.getExtensions();
- ShInitBuiltInResources(&mResources);
+ sh::InitBuiltInResources(&mResources);
mResources.MaxVertexAttribs = caps.maxVertexAttributes;
mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
mResources.MaxVaryingVectors = caps.maxVaryingVectors;
@@ -50,30 +70,79 @@ Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data)
mResources.OES_standard_derivatives = extensions.standardDerivatives;
mResources.EXT_draw_buffers = extensions.drawBuffers;
mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD;
- // TODO: disabled until the extension is actually supported.
- mResources.OES_EGL_image_external = 0;
+ mResources.OES_EGL_image_external = extensions.eglImageExternal;
+ mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
+ mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
+ mResources.ARB_texture_rectangle = extensions.textureRectangle;
// TODO: use shader precision caps to determine if high precision is supported?
mResources.FragmentPrecisionHigh = 1;
mResources.EXT_frag_depth = extensions.fragDepth;
+ // OVR_multiview state
+ mResources.OVR_multiview = extensions.multiview;
+ mResources.MaxViewsOVR = extensions.maxViews;
+
// GLSL ES 3.0 constants
mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
-}
-Compiler::~Compiler()
-{
- release();
- SafeDelete(mImplementation);
+ // GLSL ES 3.1 constants
+ mResources.MaxProgramTextureGatherOffset = caps.maxProgramTextureGatherOffset;
+ mResources.MinProgramTextureGatherOffset = caps.minProgramTextureGatherOffset;
+ mResources.MaxImageUnits = caps.maxImageUnits;
+ mResources.MaxVertexImageUniforms = caps.maxVertexImageUniforms;
+ mResources.MaxFragmentImageUniforms = caps.maxFragmentImageUniforms;
+ mResources.MaxComputeImageUniforms = caps.maxComputeImageUniforms;
+ mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms;
+ mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
+ mResources.MaxUniformLocations = caps.maxUniformLocations;
+
+ for (size_t index = 0u; index < 3u; ++index)
+ {
+ mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
+ mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index];
+ }
+
+ mResources.MaxComputeUniformComponents = caps.maxComputeUniformComponents;
+ mResources.MaxComputeTextureImageUnits = caps.maxComputeTextureImageUnits;
+
+ mResources.MaxComputeAtomicCounters = caps.maxComputeAtomicCounters;
+ mResources.MaxComputeAtomicCounterBuffers = caps.maxComputeAtomicCounterBuffers;
+
+ mResources.MaxVertexAtomicCounters = caps.maxVertexAtomicCounters;
+ mResources.MaxFragmentAtomicCounters = caps.maxFragmentAtomicCounters;
+ mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
+ mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings;
+ mResources.MaxVertexAtomicCounterBuffers = caps.maxVertexAtomicCounterBuffers;
+ mResources.MaxFragmentAtomicCounterBuffers = caps.maxFragmentAtomicCounterBuffers;
+ mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
+ mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize;
+
+ mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings;
+ mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
+
+ // Needed by point size clamping workaround
+ mResources.MaxPointSize = caps.maxAliasedPointSize;
+
+ if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers)
+ {
+ mResources.MaxDrawBuffers = 1;
+ }
+
+ // Geometry Shader constants
+ mResources.OES_geometry_shader = extensions.geometryShader;
+ // TODO(jiawei.shao@intel.com): initialize all implementation dependent geometry shader limits.
+ mResources.MaxGeometryOutputVertices = extensions.maxGeometryOutputVertices;
+ mResources.MaxGeometryShaderInvocations = extensions.maxGeometryShaderInvocations;
}
-Error Compiler::release()
+Compiler::~Compiler()
{
if (mFragmentCompiler)
{
- ShDestruct(mFragmentCompiler);
+ sh::Destruct(mFragmentCompiler);
mFragmentCompiler = nullptr;
ASSERT(activeCompilerHandles > 0);
@@ -82,21 +151,28 @@ Error Compiler::release()
if (mVertexCompiler)
{
- ShDestruct(mVertexCompiler);
+ sh::Destruct(mVertexCompiler);
mVertexCompiler = nullptr;
ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--;
}
- if (activeCompilerHandles == 0)
+ if (mComputeCompiler)
{
- ShFinalize();
+ sh::Destruct(mComputeCompiler);
+ mComputeCompiler = nullptr;
+
+ ASSERT(activeCompilerHandles > 0);
+ activeCompilerHandles--;
}
- mImplementation->release();
+ if (activeCompilerHandles == 0)
+ {
+ sh::Finalize();
+ }
- return gl::Error(GL_NO_ERROR);
+ ANGLE_SWALLOW_ERR(mImplementation->release());
}
ShHandle Compiler::getCompilerHandle(GLenum type)
@@ -111,7 +187,12 @@ ShHandle Compiler::getCompilerHandle(GLenum type)
case GL_FRAGMENT_SHADER:
compiler = &mFragmentCompiler;
break;
-
+ case GL_COMPUTE_SHADER:
+ compiler = &mComputeCompiler;
+ break;
+ case GL_GEOMETRY_SHADER_EXT:
+ compiler = &mGeometryCompiler;
+ break;
default:
UNREACHABLE();
return nullptr;
@@ -121,14 +202,20 @@ ShHandle Compiler::getCompilerHandle(GLenum type)
{
if (activeCompilerHandles == 0)
{
- ShInitialize();
+ sh::Initialize();
}
- *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources);
+ *compiler = sh::ConstructCompiler(type, mSpec, mOutputType, &mResources);
+ ASSERT(*compiler);
activeCompilerHandles++;
}
return *compiler;
}
+const std::string &Compiler::getBuiltinResourcesString(GLenum type)
+{
+ return sh::GetBuiltInResourcesString(getCompilerHandle(type));
+}
+
} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.h b/src/3rdparty/angle/src/libANGLE/Compiler.h
index 8634e39a45..b7f7e9f31b 100644
--- a/src/3rdparty/angle/src/libANGLE/Compiler.h
+++ b/src/3rdparty/angle/src/libANGLE/Compiler.h
@@ -10,38 +10,40 @@
#ifndef LIBANGLE_COMPILER_H_
#define LIBANGLE_COMPILER_H_
-#include "libANGLE/Error.h"
#include "GLSLANG/ShaderLang.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
namespace rx
{
class CompilerImpl;
-class ImplFactory;
+class GLImplFactory;
}
namespace gl
{
-struct Data;
+class ContextState;
-class Compiler final : angle::NonCopyable
+class Compiler final : public RefCountObjectNoID
{
public:
- Compiler(rx::ImplFactory *implFactory, const Data &data);
- ~Compiler();
-
- Error release();
+ Compiler(rx::GLImplFactory *implFactory, const ContextState &data);
ShHandle getCompilerHandle(GLenum type);
ShShaderOutput getShaderOutputType() const { return mOutputType; }
+ const std::string &getBuiltinResourcesString(GLenum type);
private:
- rx::CompilerImpl *mImplementation;
+ ~Compiler() override;
+ std::unique_ptr<rx::CompilerImpl> mImplementation;
ShShaderSpec mSpec;
ShShaderOutput mOutputType;
ShBuiltInResources mResources;
ShHandle mFragmentCompiler;
ShHandle mVertexCompiler;
+ ShHandle mComputeCompiler;
+ ShHandle mGeometryCompiler;
};
} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Config.cpp b/src/3rdparty/angle/src/libANGLE/Config.cpp
index d511df3a69..172c312ae0 100644
--- a/src/3rdparty/angle/src/libANGLE/Config.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Config.cpp
@@ -58,10 +58,27 @@ Config::Config()
transparentRedValue(0),
transparentGreenValue(0),
transparentBlueValue(0),
- optimalOrientation(0)
+ optimalOrientation(0),
+ colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
{
}
+Config::~Config()
+{
+}
+
+Config::Config(const Config &other) = default;
+
+Config &Config::operator=(const Config &other) = default;
+
+ConfigSet::ConfigSet() = default;
+
+ConfigSet::ConfigSet(const ConfigSet &other) = default;
+
+ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;
+
+ConfigSet::~ConfigSet() = default;
+
EGLint ConfigSet::add(const Config &config)
{
// Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
@@ -134,6 +151,10 @@ class ConfigSorter
static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value.");
SORT(configCaveat);
+ static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+ "Unexpected order of EGL enums.");
+ SORT(colorComponentType);
+
static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
SORT(colorBufferType);
@@ -160,6 +181,7 @@ class ConfigSorter
}
private:
+
void scanForWantedComponents(const AttributeMap &attributeMap)
{
// [EGL 1.5] section 3.4.1.2 page 30
@@ -215,8 +237,13 @@ std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) c
for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
{
- EGLint attributeKey = attribIter->first;
- EGLint attributeValue = attribIter->second;
+ EGLAttrib attributeKey = attribIter->first;
+ EGLAttrib attributeValue = attribIter->second;
+
+ if (attributeValue == EGL_DONT_CARE)
+ {
+ continue;
+ }
switch (attributeKey)
{
@@ -255,6 +282,9 @@ std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) c
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
match = config.optimalOrientation == attributeValue;
break;
+ case EGL_COLOR_COMPONENT_TYPE_EXT:
+ match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
+ break;
default: UNREACHABLE();
}
diff --git a/src/3rdparty/angle/src/libANGLE/Config.h b/src/3rdparty/angle/src/libANGLE/Config.h
index 00f5673b59..f2fbe8b95a 100644
--- a/src/3rdparty/angle/src/libANGLE/Config.h
+++ b/src/3rdparty/angle/src/libANGLE/Config.h
@@ -27,6 +27,9 @@ namespace egl
struct Config
{
Config();
+ ~Config();
+ Config(const Config &other);
+ Config &operator=(const Config &other);
GLenum renderTargetFormat; // TODO(geofflang): remove this
GLenum depthStencilFormat; // TODO(geofflang): remove this
@@ -65,11 +68,17 @@ struct Config
EGLint transparentGreenValue; // Transparent green value
EGLint transparentBlueValue; // Transparent blue value
EGLint optimalOrientation; // Optimal window surface orientation
+ EGLenum colorComponentType; // Color component type
};
class ConfigSet
{
public:
+ ConfigSet();
+ ConfigSet(const ConfigSet &other);
+ ~ConfigSet();
+ ConfigSet &operator=(const ConfigSet &other);
+
EGLint add(const Config &config);
const Config &get(EGLint id) const;
@@ -83,7 +92,7 @@ class ConfigSet
std::vector<const Config*> filter(const AttributeMap &attributeMap) const;
private:
- typedef std::map<EGLint, const Config> ConfigMap;
+ typedef std::map<EGLint, Config> ConfigMap;
ConfigMap mConfigs;
};
diff --git a/src/3rdparty/angle/src/libANGLE/Constants.h b/src/3rdparty/angle/src/libANGLE/Constants.h
index dc8f9555b8..2fe921af38 100644
--- a/src/3rdparty/angle/src/libANGLE/Constants.h
+++ b/src/3rdparty/angle/src/libANGLE/Constants.h
@@ -9,36 +9,54 @@
#ifndef LIBANGLE_CONSTANTS_H_
#define LIBANGLE_CONSTANTS_H_
+#include "common/platform.h"
+
namespace gl
{
+// The binary cache is currently left disable by default, and the application can enable it.
+const size_t kDefaultMaxProgramCacheMemoryBytes = 0;
+
enum
{
- MAX_VERTEX_ATTRIBS = 16,
+ // Implementation upper limits, real maximums depend on the hardware
+ MAX_SAMPLE_MASK_WORDS = 2,
+
+ MAX_VERTEX_ATTRIBS = 16,
+ MAX_VERTEX_ATTRIB_BINDINGS = 16,
// Implementation upper limits, real maximums depend on the hardware
IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
- IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
- IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
+ IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
+ IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS =
+ IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
- IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16,
+ IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16,
IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16,
- IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS +
- IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS,
+ IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS =
+ IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS +
+ IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS,
IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4,
+ // Maximum number of views which are supported by the implementation of ANGLE_multiview.
+ IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS = 4,
+
// These are the maximums the implementation can support
// The actual GL caps are limited by the device caps
// and should be queried from the Context
- IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
- IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
- IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
+ IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
+ IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
+ IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
- IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
-};
+ // 1+log2 of max of MAX_*_TEXTURE_SIZE
+ IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15,
+ // Limit active textures so we can use fast bitsets.
+ IMPLEMENTATION_MAX_SHADER_TEXTURES = 32,
+ IMPLEMENTATION_MAX_ACTIVE_TEXTURES = IMPLEMENTATION_MAX_SHADER_TEXTURES * 2,
+};
}
#endif // LIBANGLE_CONSTANTS_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp
index 26f2970068..f638beda58 100644
--- a/src/3rdparty/angle/src/libANGLE/Context.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Context.cpp
@@ -9,18 +9,24 @@
#include "libANGLE/Context.h"
+#include <string.h>
#include <iterator>
#include <sstream>
+#include <vector>
+#include "common/matrix_utils.h"
#include "common/platform.h"
#include "common/utilities.h"
+#include "common/version.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/Compiler.h"
#include "libANGLE/Display.h"
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Path.h"
#include "libANGLE/Program.h"
+#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/Query.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/ResourceManager.h"
@@ -29,36 +35,97 @@
#include "libANGLE/Texture.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/VertexArray.h"
+#include "libANGLE/Workarounds.h"
#include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
+#include "libANGLE/renderer/Format.h"
#include "libANGLE/validationES.h"
-#include "libANGLE/renderer/Renderer.h"
namespace
{
+#define ANGLE_HANDLE_ERR(X) \
+ handleError(X); \
+ return;
+#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
+
+template <typename T>
+std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
+ GLsizei numPaths,
+ const void *paths,
+ GLuint pathBase)
+{
+ std::vector<gl::Path *> ret;
+ ret.reserve(numPaths);
+
+ const auto *nameArray = static_cast<const T *>(paths);
+
+ for (GLsizei i = 0; i < numPaths; ++i)
+ {
+ const GLuint pathName = nameArray[i] + pathBase;
+
+ ret.push_back(resourceManager.getPath(pathName));
+ }
+
+ return ret;
+}
+
+std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
+ GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase)
+{
+ switch (pathNameType)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
+
+ case GL_BYTE:
+ return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
+
+ case GL_UNSIGNED_SHORT:
+ return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
+
+ case GL_SHORT:
+ return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
+
+ case GL_UNSIGNED_INT:
+ return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
+
+ case GL_INT:
+ return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
+ }
+
+ UNREACHABLE();
+ return std::vector<gl::Path *>();
+}
+
template <typename T>
-gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
+gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
{
- gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
- ASSERT(queryObject != nullptr);
+ ASSERT(query != nullptr);
switch (pname)
{
case GL_QUERY_RESULT_EXT:
- return queryObject->getResult(params);
+ return query->getResult(params);
case GL_QUERY_RESULT_AVAILABLE_EXT:
{
bool available;
- gl::Error error = queryObject->isResultAvailable(&available);
+ gl::Error error = query->isResultAvailable(&available);
if (!error.isError())
{
- *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
+ *params = gl::CastFromStateValue<T>(pname, static_cast<GLuint>(available));
}
return error;
}
default:
UNREACHABLE();
- return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
+ return gl::InternalError() << "Unreachable Error";
}
}
@@ -69,7 +136,7 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
tfBufferIndex++)
{
- const OffsetBindingPointer<gl::Buffer> &buffer =
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer =
transformFeedback->getIndexedBuffer(tfBufferIndex);
if (buffer.get() != nullptr)
{
@@ -80,15 +147,25 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
}
// Attribute map queries.
-EGLint GetClientVersion(const egl::AttributeMap &attribs)
+EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
+{
+ return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
+}
+
+EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
+{
+ return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
+}
+
+gl::Version GetClientVersion(const egl::AttributeMap &attribs)
{
- return attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
+ return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
}
GLenum GetResetStrategy(const egl::AttributeMap &attribs)
{
- EGLenum attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
- EGL_NO_RESET_NOTIFICATION_EXT);
+ EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
+ EGL_NO_RESET_NOTIFICATION);
switch (attrib)
{
case EGL_NO_RESET_NOTIFICATION:
@@ -103,12 +180,15 @@ GLenum GetResetStrategy(const egl::AttributeMap &attribs)
bool GetRobustAccess(const egl::AttributeMap &attribs)
{
- return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
+ return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
+ ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
+ 0);
}
bool GetDebug(const egl::AttributeMap &attribs)
{
- return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
+ return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
+ ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
}
bool GetNoError(const egl::AttributeMap &attribs)
@@ -116,504 +196,657 @@ bool GetNoError(const egl::AttributeMap &attribs)
return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
}
+bool GetWebGLContext(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
+}
+
+bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
+}
+
+bool GetRobustResourceInit(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
+{
+ std::string labelName;
+ if (label != nullptr)
+ {
+ size_t labelLength = length < 0 ? strlen(label) : length;
+ labelName = std::string(label, labelLength);
+ }
+ return labelName;
+}
+
+void GetObjectLabelBase(const std::string &objectLabel,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ size_t writeLength = objectLabel.length();
+ if (label != nullptr && bufSize > 0)
+ {
+ writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
+ std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
+ label[writeLength] = '\0';
+ }
+
+ if (length != nullptr)
+ {
+ *length = static_cast<GLsizei>(writeLength);
+ }
+}
+
+template <typename CapT, typename MaxT>
+void LimitCap(CapT *cap, MaxT maximum)
+{
+ *cap = std::min(*cap, static_cast<CapT>(maximum));
+}
+
} // anonymous namespace
namespace gl
{
-Context::Context(const egl::Config *config,
+Context::Context(rx::EGLImplFactory *implFactory,
+ const egl::Config *config,
const Context *shareContext,
- rx::Renderer *renderer,
- const egl::AttributeMap &attribs)
- : ValidationContext(GetClientVersion(attribs),
- mState,
+ TextureManager *shareTextures,
+ MemoryProgramCache *memoryProgramCache,
+ const egl::AttributeMap &attribs,
+ const egl::DisplayExtensions &displayExtensions)
+
+ : ValidationContext(shareContext,
+ shareTextures,
+ GetClientVersion(attribs),
+ &mGLState,
mCaps,
mTextureCaps,
mExtensions,
- nullptr,
mLimitations,
GetNoError(attribs)),
- mCompiler(nullptr),
- mRenderer(renderer),
- mClientVersion(GetClientVersion(attribs)),
+ mImplementation(implFactory->createContext(mState)),
+ mCompiler(),
mConfig(config),
mClientType(EGL_OPENGL_ES_API),
mHasBeenCurrent(false),
mContextLost(false),
mResetStatus(GL_NO_ERROR),
+ mContextLostForced(false),
mResetStrategy(GetResetStrategy(attribs)),
mRobustAccess(GetRobustAccess(attribs)),
- mCurrentSurface(nullptr),
- mResourceManager(nullptr)
+ mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
+ mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
+ mSurfacelessFramebuffer(nullptr),
+ mWebGLContext(GetWebGLContext(attribs)),
+ mMemoryProgramCache(memoryProgramCache),
+ mScratchBuffer(1000u),
+ mZeroFilledBuffer(1000u)
{
- ASSERT(!mRobustAccess); // Unimplemented
+ mImplementation->setMemoryProgramCache(memoryProgramCache);
- initCaps(mClientVersion);
+ bool robustResourceInit = GetRobustResourceInit(attribs);
+ initCaps(displayExtensions, robustResourceInit);
+ initWorkarounds();
- mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
+ mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
+ GetClientArraysEnabled(attribs), robustResourceInit,
+ mMemoryProgramCache != nullptr);
mFenceNVHandleAllocator.setBaseHandle(0);
- if (shareContext != NULL)
- {
- mResourceManager = shareContext->mResourceManager;
- mResourceManager->addRef();
- }
- else
- {
- mResourceManager = new ResourceManager(mRenderer);
- }
-
- mData.resourceManager = mResourceManager;
-
// [OpenGL ES 2.0.24] section 3.7 page 83:
- // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+ // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
// and cube map texture state vectors respectively associated with them.
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 0, GL_TEXTURE_2D);
- mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
+ Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
+ mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
- Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0, GL_TEXTURE_CUBE_MAP);
- mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
+ Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
+ mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
- if (mClientVersion >= 3)
+ if (getClientVersion() >= Version(3, 0))
{
// TODO: These could also be enabled via extension
- Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 0, GL_TEXTURE_3D);
- mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
+ Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
+ mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
- Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0, GL_TEXTURE_2D_ARRAY);
- mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
+ Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
+ mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
}
+ if (getClientVersion() >= Version(3, 1))
+ {
+ Texture *zeroTexture2DMultisample =
+ new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
+ mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
- mState.initializeZeroTextures(mZeroTextures);
+ for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
+ {
+ bindBufferRange(BufferBinding::AtomicCounter, 0, i, 0, 0);
+ }
- bindVertexArray(0);
- bindArrayBuffer(0);
- bindElementArrayBuffer(0);
+ for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
+ {
+ bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0);
+ }
+ }
- bindRenderbuffer(0);
+ const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
+ if (nativeExtensions.textureRectangle)
+ {
+ Texture *zeroTextureRectangle =
+ new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
+ mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
+ }
- bindGenericUniformBuffer(0);
- for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
+ if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
{
- bindIndexedUniformBuffer(0, i, 0, -1);
+ Texture *zeroTextureExternal =
+ new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
+ mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
}
- bindCopyReadBuffer(0);
- bindCopyWriteBuffer(0);
- bindPixelPackBuffer(0);
- bindPixelUnpackBuffer(0);
+ mGLState.initializeZeroTextures(this, mZeroTextures);
- if (mClientVersion >= 3)
+ bindVertexArray(0);
+
+ if (getClientVersion() >= Version(3, 0))
{
// [OpenGL ES 3.0.2] section 2.14.1 pg 85:
// In the initial state, a default transform feedback object is bound and treated as
// a transform feedback object with a name of zero. That object is bound any time
// BindTransformFeedback is called with id of zero
- bindTransformFeedback(0);
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
}
- mCompiler = new Compiler(mRenderer, getData());
-}
+ for (auto type : angle::AllEnums<BufferBinding>())
+ {
+ bindBuffer(type, 0);
+ }
-Context::~Context()
-{
- mState.reset();
+ bindRenderbuffer(GL_RENDERBUFFER, 0);
- for (auto framebuffer : mFramebufferMap)
+ for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
{
- // Default framebuffer are owned by their respective Surface
- if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
- {
- SafeDelete(framebuffer.second);
- }
+ bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1);
}
+ // Initialize dirty bit masks
+ mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
+ mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
+ // No dirty objects.
+
+ // Readpixels uses the pack state and read FBO
+ mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
+ mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
+ mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
+
+ mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
+ mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
+ mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
+ mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
+ mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
+ mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+
+ mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
+ mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+
+ handleError(mImplementation->initialize());
+}
+
+egl::Error Context::onDestroy(const egl::Display *display)
+{
for (auto fence : mFenceNVMap)
{
SafeDelete(fence.second);
}
+ mFenceNVMap.clear();
for (auto query : mQueryMap)
{
if (query.second != nullptr)
{
- query.second->release();
+ query.second->release(this);
}
}
+ mQueryMap.clear();
for (auto vertexArray : mVertexArrayMap)
{
- SafeDelete(vertexArray.second);
+ if (vertexArray.second)
+ {
+ vertexArray.second->onDestroy(this);
+ }
}
+ mVertexArrayMap.clear();
for (auto transformFeedback : mTransformFeedbackMap)
{
if (transformFeedback.second != nullptr)
{
- transformFeedback.second->release();
+ transformFeedback.second->release(this);
}
}
+ mTransformFeedbackMap.clear();
for (auto &zeroTexture : mZeroTextures)
{
- zeroTexture.second.set(NULL);
+ ANGLE_TRY(zeroTexture.second->onDestroy(this));
+ zeroTexture.second.set(this, nullptr);
}
mZeroTextures.clear();
- if (mCurrentSurface != nullptr)
- {
- releaseSurface();
- }
+ SafeDelete(mSurfacelessFramebuffer);
- if (mResourceManager)
- {
- mResourceManager->release();
- }
+ ANGLE_TRY(releaseSurface(display));
+ releaseShaderCompiler();
+
+ mGLState.reset(this);
- SafeDelete(mCompiler);
+ mState.mBuffers->release(this);
+ mState.mShaderPrograms->release(this);
+ mState.mTextures->release(this);
+ mState.mRenderbuffers->release(this);
+ mState.mSamplers->release(this);
+ mState.mSyncs->release(this);
+ mState.mPaths->release(this);
+ mState.mFramebuffers->release(this);
+ mState.mPipelines->release(this);
+
+ mImplementation->onDestroy(this);
+
+ return egl::NoError();
+}
+
+Context::~Context()
+{
}
-void Context::makeCurrent(egl::Surface *surface)
+egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
- ASSERT(surface != nullptr);
+ mCurrentDisplay = display;
if (!mHasBeenCurrent)
{
initRendererString();
+ initVersionStrings();
initExtensionStrings();
- mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
- mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
+ int width = 0;
+ int height = 0;
+ if (surface != nullptr)
+ {
+ width = surface->getWidth();
+ height = surface->getHeight();
+ }
+
+ mGLState.setViewportParams(0, 0, width, height);
+ mGLState.setScissorParams(0, 0, width, height);
mHasBeenCurrent = true;
}
// TODO(jmadill): Rework this when we support ContextImpl
- mState.setAllDirtyBits();
+ mGLState.setAllDirtyBits();
+ mGLState.setAllDirtyObjects();
- if (mCurrentSurface)
+ ANGLE_TRY(releaseSurface(display));
+
+ Framebuffer *newDefault = nullptr;
+ if (surface != nullptr)
+ {
+ ANGLE_TRY(surface->setIsCurrent(this, true));
+ mCurrentSurface = surface;
+ newDefault = surface->getDefaultFramebuffer();
+ }
+ else
{
- releaseSurface();
+ if (mSurfacelessFramebuffer == nullptr)
+ {
+ mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
+ }
+
+ newDefault = mSurfacelessFramebuffer;
}
- surface->setIsCurrent(true);
- mCurrentSurface = surface;
// Update default framebuffer, the binding of the previous default
// framebuffer (or lack of) will have a nullptr.
{
- Framebuffer *newDefault = surface->getDefaultFramebuffer();
- if (mState.getReadFramebuffer() == nullptr)
+ if (mGLState.getReadFramebuffer() == nullptr)
{
- mState.setReadFramebufferBinding(newDefault);
+ mGLState.setReadFramebufferBinding(newDefault);
}
- if (mState.getDrawFramebuffer() == nullptr)
+ if (mGLState.getDrawFramebuffer() == nullptr)
{
- mState.setDrawFramebufferBinding(newDefault);
+ mGLState.setDrawFramebufferBinding(newDefault);
}
- mFramebufferMap[0] = newDefault;
+ mState.mFramebuffers->setDefaultFramebuffer(newDefault);
}
// Notify the renderer of a context switch
- mRenderer->onMakeCurrent(getData());
+ mImplementation->onMakeCurrent(this);
+ return egl::NoError();
}
-void Context::releaseSurface()
+egl::Error Context::releaseSurface(const egl::Display *display)
{
- ASSERT(mCurrentSurface != nullptr);
-
// Remove the default framebuffer
+ Framebuffer *currentDefault = nullptr;
+ if (mCurrentSurface != nullptr)
{
- Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
- if (mState.getReadFramebuffer() == currentDefault)
- {
- mState.setReadFramebufferBinding(nullptr);
- }
- if (mState.getDrawFramebuffer() == currentDefault)
- {
- mState.setDrawFramebufferBinding(nullptr);
- }
- mFramebufferMap.erase(0);
+ currentDefault = mCurrentSurface->getDefaultFramebuffer();
+ }
+ else if (mSurfacelessFramebuffer != nullptr)
+ {
+ currentDefault = mSurfacelessFramebuffer;
}
- mCurrentSurface->setIsCurrent(false);
- mCurrentSurface = nullptr;
-}
+ if (mGLState.getReadFramebuffer() == currentDefault)
+ {
+ mGLState.setReadFramebufferBinding(nullptr);
+ }
+ if (mGLState.getDrawFramebuffer() == currentDefault)
+ {
+ mGLState.setDrawFramebufferBinding(nullptr);
+ }
+ mState.mFramebuffers->setDefaultFramebuffer(nullptr);
-// NOTE: this function should not assume that this context is current!
-void Context::markContextLost()
-{
- if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
- mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
- mContextLost = true;
-}
+ if (mCurrentSurface)
+ {
+ ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
+ mCurrentSurface = nullptr;
+ }
-bool Context::isContextLost()
-{
- return mContextLost;
+ return egl::NoError();
}
GLuint Context::createBuffer()
{
- return mResourceManager->createBuffer();
+ return mState.mBuffers->createBuffer();
}
GLuint Context::createProgram()
{
- return mResourceManager->createProgram();
+ return mState.mShaderPrograms->createProgram(mImplementation.get());
}
GLuint Context::createShader(GLenum type)
{
- return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
+ return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
}
GLuint Context::createTexture()
{
- return mResourceManager->createTexture();
+ return mState.mTextures->createTexture();
}
GLuint Context::createRenderbuffer()
{
- return mResourceManager->createRenderbuffer();
-}
-
-GLsync Context::createFenceSync()
-{
- GLuint handle = mResourceManager->createFenceSync();
-
- return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
-}
-
-GLuint Context::createVertexArray()
-{
- GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
- mVertexArrayMap[vertexArray] = nullptr;
- return vertexArray;
-}
-
-GLuint Context::createSampler()
-{
- return mResourceManager->createSampler();
+ return mState.mRenderbuffers->createRenderbuffer();
}
-GLuint Context::createTransformFeedback()
+GLuint Context::createPaths(GLsizei range)
{
- GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
- mTransformFeedbackMap[transformFeedback] = nullptr;
- return transformFeedback;
+ auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
+ if (resultOrError.isError())
+ {
+ handleError(resultOrError.getError());
+ return 0;
+ }
+ return resultOrError.getResult();
}
// Returns an unused framebuffer name
GLuint Context::createFramebuffer()
{
- GLuint handle = mFramebufferHandleAllocator.allocate();
-
- mFramebufferMap[handle] = NULL;
-
- return handle;
+ return mState.mFramebuffers->createFramebuffer();
}
GLuint Context::createFenceNV()
{
GLuint handle = mFenceNVHandleAllocator.allocate();
-
- mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
-
+ mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
return handle;
}
-// Returns an unused query name
-GLuint Context::createQuery()
+GLuint Context::createProgramPipeline()
{
- GLuint handle = mQueryHandleAllocator.allocate();
-
- mQueryMap[handle] = NULL;
+ return mState.mPipelines->createProgramPipeline();
+}
- return handle;
+GLuint Context::createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
+{
+ UNIMPLEMENTED();
+ return 0u;
}
void Context::deleteBuffer(GLuint buffer)
{
- if (mResourceManager->getBuffer(buffer))
+ if (mState.mBuffers->getBuffer(buffer))
{
detachBuffer(buffer);
}
- mResourceManager->deleteBuffer(buffer);
+ mState.mBuffers->deleteObject(this, buffer);
}
void Context::deleteShader(GLuint shader)
{
- mResourceManager->deleteShader(shader);
+ mState.mShaderPrograms->deleteShader(this, shader);
}
void Context::deleteProgram(GLuint program)
{
- mResourceManager->deleteProgram(program);
+ mState.mShaderPrograms->deleteProgram(this, program);
}
void Context::deleteTexture(GLuint texture)
{
- if (mResourceManager->getTexture(texture))
+ if (mState.mTextures->getTexture(texture))
{
detachTexture(texture);
}
- mResourceManager->deleteTexture(texture);
+ mState.mTextures->deleteObject(this, texture);
}
void Context::deleteRenderbuffer(GLuint renderbuffer)
{
- if (mResourceManager->getRenderbuffer(renderbuffer))
+ if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
{
detachRenderbuffer(renderbuffer);
}
- mResourceManager->deleteRenderbuffer(renderbuffer);
+ mState.mRenderbuffers->deleteObject(this, renderbuffer);
}
-void Context::deleteFenceSync(GLsync fenceSync)
+void Context::deleteSync(GLsync sync)
{
// The spec specifies the underlying Fence object is not deleted until all current
// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
// and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately.
- mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
+ mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
}
-void Context::deleteVertexArray(GLuint vertexArray)
+void Context::deleteProgramPipeline(GLuint pipeline)
{
- auto iter = mVertexArrayMap.find(vertexArray);
- if (iter != mVertexArrayMap.end())
+ if (mState.mPipelines->getProgramPipeline(pipeline))
{
- VertexArray *vertexArrayObject = iter->second;
- if (vertexArrayObject != nullptr)
- {
- detachVertexArray(vertexArray);
- delete vertexArrayObject;
- }
-
- mVertexArrayMap.erase(iter);
- mVertexArrayHandleAllocator.release(vertexArray);
+ detachProgramPipeline(pipeline);
}
+
+ mState.mPipelines->deleteObject(this, pipeline);
}
-void Context::deleteSampler(GLuint sampler)
+void Context::deletePaths(GLuint first, GLsizei range)
{
- if (mResourceManager->getSampler(sampler))
- {
- detachSampler(sampler);
- }
-
- mResourceManager->deleteSampler(sampler);
+ mState.mPaths->deletePaths(first, range);
}
-void Context::deleteTransformFeedback(GLuint transformFeedback)
+bool Context::hasPathData(GLuint path) const
{
- auto iter = mTransformFeedbackMap.find(transformFeedback);
- if (iter != mTransformFeedbackMap.end())
- {
- TransformFeedback *transformFeedbackObject = iter->second;
- if (transformFeedbackObject != nullptr)
- {
- detachTransformFeedback(transformFeedback);
- transformFeedbackObject->release();
- }
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (pathObj == nullptr)
+ return false;
- mTransformFeedbackMap.erase(iter);
- mTransformFeedbackAllocator.release(transformFeedback);
- }
+ return pathObj->hasPathData();
}
-void Context::deleteFramebuffer(GLuint framebuffer)
+bool Context::hasPath(GLuint path) const
{
- FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
+ return mState.mPaths->hasPath(path);
+}
- if (framebufferObject != mFramebufferMap.end())
- {
- detachFramebuffer(framebuffer);
+void Context::setPathCommands(GLuint path,
+ GLsizei numCommands,
+ const GLubyte *commands,
+ GLsizei numCoords,
+ GLenum coordType,
+ const void *coords)
+{
+ auto *pathObject = mState.mPaths->getPath(path);
- mFramebufferHandleAllocator.release(framebufferObject->first);
- delete framebufferObject->second;
- mFramebufferMap.erase(framebufferObject);
- }
+ handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
}
-void Context::deleteFenceNV(GLuint fence)
+void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
{
- FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
+ auto *pathObj = mState.mPaths->getPath(path);
- if (fenceObject != mFenceNVMap.end())
+ switch (pname)
{
- mFenceNVHandleAllocator.release(fenceObject->first);
- delete fenceObject->second;
- mFenceNVMap.erase(fenceObject);
+ case GL_PATH_STROKE_WIDTH_CHROMIUM:
+ pathObj->setStrokeWidth(value);
+ break;
+ case GL_PATH_END_CAPS_CHROMIUM:
+ pathObj->setEndCaps(static_cast<GLenum>(value));
+ break;
+ case GL_PATH_JOIN_STYLE_CHROMIUM:
+ pathObj->setJoinStyle(static_cast<GLenum>(value));
+ break;
+ case GL_PATH_MITER_LIMIT_CHROMIUM:
+ pathObj->setMiterLimit(value);
+ break;
+ case GL_PATH_STROKE_BOUND_CHROMIUM:
+ pathObj->setStrokeBound(value);
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
-void Context::deleteQuery(GLuint query)
+void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
{
- QueryMap::iterator queryObject = mQueryMap.find(query);
- if (queryObject != mQueryMap.end())
+ const auto *pathObj = mState.mPaths->getPath(path);
+
+ switch (pname)
{
- mQueryHandleAllocator.release(queryObject->first);
- if (queryObject->second)
- {
- queryObject->second->release();
- }
- mQueryMap.erase(queryObject);
+ case GL_PATH_STROKE_WIDTH_CHROMIUM:
+ *value = pathObj->getStrokeWidth();
+ break;
+ case GL_PATH_END_CAPS_CHROMIUM:
+ *value = static_cast<GLfloat>(pathObj->getEndCaps());
+ break;
+ case GL_PATH_JOIN_STYLE_CHROMIUM:
+ *value = static_cast<GLfloat>(pathObj->getJoinStyle());
+ break;
+ case GL_PATH_MITER_LIMIT_CHROMIUM:
+ *value = pathObj->getMiterLimit();
+ break;
+ case GL_PATH_STROKE_BOUND_CHROMIUM:
+ *value = pathObj->getStrokeBound();
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
-Buffer *Context::getBuffer(GLuint handle) const
+void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ mGLState.setPathStencilFunc(func, ref, mask);
+}
+
+void Context::deleteFramebuffer(GLuint framebuffer)
{
- return mResourceManager->getBuffer(handle);
+ if (mState.mFramebuffers->getFramebuffer(framebuffer))
+ {
+ detachFramebuffer(framebuffer);
+ }
+
+ mState.mFramebuffers->deleteObject(this, framebuffer);
}
-Shader *Context::getShader(GLuint handle) const
+void Context::deleteFenceNV(GLuint fence)
{
- return mResourceManager->getShader(handle);
+ FenceNV *fenceObject = nullptr;
+ if (mFenceNVMap.erase(fence, &fenceObject))
+ {
+ mFenceNVHandleAllocator.release(fence);
+ delete fenceObject;
+ }
}
-Program *Context::getProgram(GLuint handle) const
+Buffer *Context::getBuffer(GLuint handle) const
{
- return mResourceManager->getProgram(handle);
+ return mState.mBuffers->getBuffer(handle);
}
Texture *Context::getTexture(GLuint handle) const
{
- return mResourceManager->getTexture(handle);
+ return mState.mTextures->getTexture(handle);
}
Renderbuffer *Context::getRenderbuffer(GLuint handle) const
{
- return mResourceManager->getRenderbuffer(handle);
+ return mState.mRenderbuffers->getRenderbuffer(handle);
}
-FenceSync *Context::getFenceSync(GLsync handle) const
+Sync *Context::getSync(GLsync handle) const
{
- return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
+ return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
}
VertexArray *Context::getVertexArray(GLuint handle) const
{
- auto vertexArray = mVertexArrayMap.find(handle);
- return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
+ return mVertexArrayMap.query(handle);
}
Sampler *Context::getSampler(GLuint handle) const
{
- return mResourceManager->getSampler(handle);
+ return mState.mSamplers->getSampler(handle);
}
TransformFeedback *Context::getTransformFeedback(GLuint handle) const
{
- auto iter = mTransformFeedbackMap.find(handle);
- return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
+ return mTransformFeedbackMap.query(handle);
+}
+
+ProgramPipeline *Context::getProgramPipeline(GLuint handle) const
+{
+ return mState.mPipelines->getProgramPipeline(handle);
}
LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
@@ -648,31 +881,64 @@ LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
{
- return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
+ return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
}
-bool Context::isSampler(GLuint samplerName) const
+void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
+{
+ LabeledObject *object = getLabeledObject(identifier, name);
+ ASSERT(object != nullptr);
+
+ std::string labelName = GetObjectLabelFromPointer(length, label);
+ object->setLabel(labelName);
+
+ // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
+ // specified object is active until we do this.
+ mGLState.setObjectDirty(identifier);
+}
+
+void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
{
- return mResourceManager->isSampler(samplerName);
+ LabeledObject *object = getLabeledObjectFromPtr(ptr);
+ ASSERT(object != nullptr);
+
+ std::string labelName = GetObjectLabelFromPointer(length, label);
+ object->setLabel(labelName);
}
-void Context::bindArrayBuffer(unsigned int buffer)
+void Context::getObjectLabel(GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label) const
{
- mResourceManager->checkBufferAllocation(buffer);
+ LabeledObject *object = getLabeledObject(identifier, name);
+ ASSERT(object != nullptr);
- mState.setArrayBufferBinding(getBuffer(buffer));
+ const std::string &objectLabel = object->getLabel();
+ GetObjectLabelBase(objectLabel, bufSize, length, label);
}
-void Context::bindElementArrayBuffer(unsigned int buffer)
+void Context::getObjectPtrLabel(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label) const
{
- mResourceManager->checkBufferAllocation(buffer);
+ LabeledObject *object = getLabeledObjectFromPtr(ptr);
+ ASSERT(object != nullptr);
- mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
+ const std::string &objectLabel = object->getLabel();
+ GetObjectLabelBase(objectLabel, bufSize, length, label);
+}
+
+bool Context::isSampler(GLuint samplerName) const
+{
+ return mState.mSamplers->isSampler(samplerName);
}
void Context::bindTexture(GLenum target, GLuint handle)
{
- Texture *texture = NULL;
+ Texture *texture = nullptr;
if (handle == 0)
{
@@ -680,156 +946,118 @@ void Context::bindTexture(GLenum target, GLuint handle)
}
else
{
- mResourceManager->checkTextureAllocation(handle, target);
- texture = getTexture(handle);
+ texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
}
ASSERT(texture);
-
- mState.setSamplerTexture(target, texture);
+ mGLState.setSamplerTexture(this, target, texture);
}
void Context::bindReadFramebuffer(GLuint framebufferHandle)
{
- Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
- mState.setReadFramebufferBinding(framebuffer);
+ Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
+ mImplementation.get(), mCaps, framebufferHandle);
+ mGLState.setReadFramebufferBinding(framebuffer);
}
void Context::bindDrawFramebuffer(GLuint framebufferHandle)
{
- Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
- mState.setDrawFramebufferBinding(framebuffer);
+ Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
+ mImplementation.get(), mCaps, framebufferHandle);
+ mGLState.setDrawFramebufferBinding(framebuffer);
}
-void Context::bindRenderbuffer(GLuint renderbuffer)
+void Context::bindVertexArray(GLuint vertexArrayHandle)
{
- mResourceManager->checkRenderbufferAllocation(renderbuffer);
-
- mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
+ VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
+ mGLState.setVertexArrayBinding(vertexArray);
}
-void Context::bindVertexArray(GLuint vertexArray)
+void Context::bindVertexBuffer(GLuint bindingIndex,
+ GLuint bufferHandle,
+ GLintptr offset,
+ GLsizei stride)
{
- checkVertexArrayAllocation(vertexArray);
-
- mState.setVertexArrayBinding(getVertexArray(vertexArray));
+ Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
+ mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
}
-void Context::bindSampler(GLuint textureUnit, GLuint sampler)
+void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
{
ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
- mResourceManager->checkSamplerAllocation(sampler);
-
- mState.setSamplerBinding(textureUnit, getSampler(sampler));
-}
-
-void Context::bindGenericUniformBuffer(GLuint buffer)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setGenericUniformBufferBinding(getBuffer(buffer));
-}
-
-void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
+ Sampler *sampler =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
+ mGLState.setSamplerBinding(this, textureUnit, sampler);
}
-void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
+void Context::bindImageTexture(GLuint unit,
+ GLuint texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
-}
-
-void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
-}
-
-void Context::bindCopyReadBuffer(GLuint buffer)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setCopyReadBufferBinding(getBuffer(buffer));
-}
-
-void Context::bindCopyWriteBuffer(GLuint buffer)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setCopyWriteBufferBinding(getBuffer(buffer));
+ Texture *tex = mState.mTextures->getTexture(texture);
+ mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
}
-void Context::bindPixelPackBuffer(GLuint buffer)
+void Context::useProgram(GLuint program)
{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setPixelPackBufferBinding(getBuffer(buffer));
+ mGLState.setProgram(this, getProgram(program));
}
-void Context::bindPixelUnpackBuffer(GLuint buffer)
+void Context::useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.setPixelUnpackBufferBinding(getBuffer(buffer));
+ UNIMPLEMENTED();
}
-void Context::useProgram(GLuint program)
+void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
{
- mState.setProgram(getProgram(program));
+ ASSERT(target == GL_TRANSFORM_FEEDBACK);
+ TransformFeedback *transformFeedback =
+ checkTransformFeedbackAllocation(transformFeedbackHandle);
+ mGLState.setTransformFeedbackBinding(this, transformFeedback);
}
-void Context::bindTransformFeedback(GLuint transformFeedback)
+void Context::bindProgramPipeline(GLuint pipelineHandle)
{
- checkTransformFeedbackAllocation(transformFeedback);
-
- mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
+ ProgramPipeline *pipeline =
+ mState.mPipelines->checkProgramPipelineAllocation(mImplementation.get(), pipelineHandle);
+ mGLState.setProgramPipelineBinding(this, pipeline);
}
-Error Context::beginQuery(GLenum target, GLuint query)
+void Context::beginQuery(GLenum target, GLuint query)
{
Query *queryObject = getQuery(query, true, target);
ASSERT(queryObject);
// begin query
- Error error = queryObject->begin();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_CONTEXT_TRY(queryObject->begin());
// set query as active for specified target only if begin succeeded
- mState.setActiveQuery(target, queryObject);
-
- return Error(GL_NO_ERROR);
+ mGLState.setActiveQuery(this, target, queryObject);
}
-Error Context::endQuery(GLenum target)
+void Context::endQuery(GLenum target)
{
- Query *queryObject = mState.getActiveQuery(target);
+ Query *queryObject = mGLState.getActiveQuery(target);
ASSERT(queryObject);
- gl::Error error = queryObject->end();
+ handleError(queryObject->end());
// Always unbind the query, even if there was an error. This may delete the query object.
- mState.setActiveQuery(target, NULL);
-
- return error;
+ mGLState.setActiveQuery(this, target, nullptr);
}
-Error Context::queryCounter(GLuint id, GLenum target)
+void Context::queryCounter(GLuint id, GLenum target)
{
ASSERT(target == GL_TIMESTAMP_EXT);
Query *queryObject = getQuery(id, true, target);
ASSERT(queryObject);
- return queryObject->queryCounter();
+ handleError(queryObject->queryCounter());
}
void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
@@ -837,7 +1065,7 @@ void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
switch (pname)
{
case GL_CURRENT_QUERY_EXT:
- params[0] = getState().getActiveQueryId(target);
+ params[0] = mGLState.getActiveQueryId(target);
break;
case GL_QUERY_COUNTER_BITS_EXT:
switch (target)
@@ -860,763 +1088,992 @@ void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
}
}
-Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
+void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
{
- return GetQueryObjectParameter(this, id, pname, params);
+ handleError(GetQueryObjectParameter(getQuery(id), pname, params));
}
-Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
+void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
{
- return GetQueryObjectParameter(this, id, pname, params);
+ handleError(GetQueryObjectParameter(getQuery(id), pname, params));
}
-Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
+void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
{
- return GetQueryObjectParameter(this, id, pname, params);
+ handleError(GetQueryObjectParameter(getQuery(id), pname, params));
}
-Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
+void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
{
- return GetQueryObjectParameter(this, id, pname, params);
+ handleError(GetQueryObjectParameter(getQuery(id), pname, params));
}
-Framebuffer *Context::getFramebuffer(unsigned int handle) const
+Framebuffer *Context::getFramebuffer(GLuint handle) const
{
- auto framebufferIt = mFramebufferMap.find(handle);
- return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
+ return mState.mFramebuffers->getFramebuffer(handle);
}
-FenceNV *Context::getFenceNV(unsigned int handle)
+FenceNV *Context::getFenceNV(GLuint handle)
{
- FenceNVMap::iterator fence = mFenceNVMap.find(handle);
-
- if (fence == mFenceNVMap.end())
- {
- return NULL;
- }
- else
- {
- return fence->second;
- }
+ return mFenceNVMap.query(handle);
}
-Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
+Query *Context::getQuery(GLuint handle, bool create, GLenum type)
{
- QueryMap::iterator query = mQueryMap.find(handle);
-
- if (query == mQueryMap.end())
+ if (!mQueryMap.contains(handle))
{
- return NULL;
+ return nullptr;
}
- else
+
+ Query *query = mQueryMap.query(handle);
+ if (!query && create)
{
- if (!query->second && create)
- {
- query->second = new Query(mRenderer->createQuery(type), handle);
- query->second->addRef();
- }
- return query->second;
+ query = new Query(mImplementation->createQuery(type), handle);
+ query->addRef();
+ mQueryMap.assign(handle, query);
}
+ return query;
}
Query *Context::getQuery(GLuint handle) const
{
- auto iter = mQueryMap.find(handle);
- return (iter != mQueryMap.end()) ? iter->second : nullptr;
+ return mQueryMap.query(handle);
}
Texture *Context::getTargetTexture(GLenum target) const
{
- ASSERT(ValidTextureTarget(this, target));
- return mState.getTargetTexture(target);
+ ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
+ return mGLState.getTargetTexture(target);
}
Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- return mState.getSamplerTexture(sampler, type);
+ return mGLState.getSamplerTexture(sampler, type);
}
Compiler *Context::getCompiler() const
{
- return mCompiler;
+ if (mCompiler.get() == nullptr)
+ {
+ mCompiler.set(this, new Compiler(mImplementation.get(), mState));
+ }
+ return mCompiler.get();
}
-void Context::getBooleanv(GLenum pname, GLboolean *params)
+void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
{
switch (pname)
{
- case GL_SHADER_COMPILER: *params = GL_TRUE; break;
- case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
- default:
- mState.getBooleanv(pname, params);
- break;
+ case GL_SHADER_COMPILER:
+ *params = GL_TRUE;
+ break;
+ case GL_CONTEXT_ROBUST_ACCESS_EXT:
+ *params = mRobustAccess ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ mGLState.getBooleanv(pname, params);
+ break;
}
}
-void Context::getFloatv(GLenum pname, GLfloat *params)
+void Context::getFloatvImpl(GLenum pname, GLfloat *params)
{
// Queries about context capabilities and maximums are answered by Context.
// Queries about current GL state values are answered by State.
switch (pname)
{
- case GL_ALIASED_LINE_WIDTH_RANGE:
- params[0] = mCaps.minAliasedLineWidth;
- params[1] = mCaps.maxAliasedLineWidth;
- break;
- case GL_ALIASED_POINT_SIZE_RANGE:
- params[0] = mCaps.minAliasedPointSize;
- params[1] = mCaps.maxAliasedPointSize;
- break;
- case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
- ASSERT(mExtensions.textureFilterAnisotropic);
- *params = mExtensions.maxTextureAnisotropy;
- break;
- case GL_MAX_TEXTURE_LOD_BIAS:
- *params = mCaps.maxLODBias;
- break;
- default:
- mState.getFloatv(pname, params);
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = mCaps.minAliasedLineWidth;
+ params[1] = mCaps.maxAliasedLineWidth;
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = mCaps.minAliasedPointSize;
+ params[1] = mCaps.maxAliasedPointSize;
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ ASSERT(mExtensions.textureFilterAnisotropic);
+ *params = mExtensions.maxTextureAnisotropy;
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS:
+ *params = mCaps.maxLODBias;
+ break;
+
+ case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
+ case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
+ {
+ ASSERT(mExtensions.pathRendering);
+ const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
+ memcpy(params, m, 16 * sizeof(GLfloat));
+ }
break;
+
+ default:
+ mGLState.getFloatv(pname, params);
+ break;
}
}
-void Context::getIntegerv(GLenum pname, GLint *params)
+void Context::getIntegervImpl(GLenum pname, GLint *params)
{
// Queries about context capabilities and maximums are answered by Context.
// Queries about current GL state values are answered by State.
switch (pname)
{
- case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
- case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
- case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
- case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
- case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
- case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
- case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
- case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
- case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
- case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
- //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
- case GL_SUBPIXEL_BITS: *params = 4; break;
- case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
- case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
- case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
- case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
- case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
- case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
- case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
- case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
- case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
- case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
- case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
- case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
- case GL_MAJOR_VERSION: *params = mClientVersion; break;
- case GL_MINOR_VERSION: *params = 0; break;
- case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
- case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
- case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
- *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
- break;
- case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
- case GL_MAX_VIEWPORT_DIMS:
+ case GL_MAX_VERTEX_ATTRIBS:
+ *params = mCaps.maxVertexAttributes;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ *params = mCaps.maxVertexUniformVectors;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+ *params = mCaps.maxVertexUniformComponents;
+ break;
+ case GL_MAX_VARYING_VECTORS:
+ *params = mCaps.maxVaryingVectors;
+ break;
+ case GL_MAX_VARYING_COMPONENTS:
+ *params = mCaps.maxVertexOutputComponents;
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ *params = mCaps.maxCombinedTextureImageUnits;
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ *params = mCaps.maxVertexTextureImageUnits;
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ *params = mCaps.maxTextureImageUnits;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ *params = mCaps.maxFragmentUniformVectors;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ *params = mCaps.maxFragmentUniformComponents;
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE:
+ *params = mCaps.maxRenderbufferSize;
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ *params = mCaps.maxColorAttachments;
+ break;
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ *params = mCaps.maxDrawBuffers;
+ break;
+ // case GL_FRAMEBUFFER_BINDING: // now equivalent to
+ // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+ case GL_SUBPIXEL_BITS:
+ *params = 4;
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ *params = mCaps.max2DTextureSize;
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
+ *params = mCaps.maxRectangleTextureSize;
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ *params = mCaps.maxCubeMapTextureSize;
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ *params = mCaps.max3DTextureSize;
+ break;
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
+ *params = mCaps.maxArrayTextureLayers;
+ break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ *params = mCaps.uniformBufferOffsetAlignment;
+ break;
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+ *params = mCaps.maxUniformBufferBindings;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+ *params = mCaps.maxVertexUniformBlocks;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+ *params = mCaps.maxFragmentUniformBlocks;
+ break;
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+ *params = mCaps.maxCombinedTextureImageUnits;
+ break;
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+ *params = mCaps.maxVertexOutputComponents;
+ break;
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+ *params = mCaps.maxFragmentInputComponents;
+ break;
+ case GL_MIN_PROGRAM_TEXEL_OFFSET:
+ *params = mCaps.minProgramTexelOffset;
+ break;
+ case GL_MAX_PROGRAM_TEXEL_OFFSET:
+ *params = mCaps.maxProgramTexelOffset;
+ break;
+ case GL_MAJOR_VERSION:
+ *params = getClientVersion().major;
+ break;
+ case GL_MINOR_VERSION:
+ *params = getClientVersion().minor;
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ *params = mCaps.maxElementsIndices;
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ *params = mCaps.maxElementsVertices;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+ *params = mCaps.maxTransformFeedbackInterleavedComponents;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+ *params = mCaps.maxTransformFeedbackSeparateAttributes;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+ *params = mCaps.maxTransformFeedbackSeparateComponents;
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
+ break;
+ case GL_MAX_SAMPLES_ANGLE:
+ *params = mCaps.maxSamples;
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
{
params[0] = mCaps.maxViewportWidth;
params[1] = mCaps.maxViewportHeight;
}
break;
- case GL_COMPRESSED_TEXTURE_FORMATS:
- std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
- break;
- case GL_RESET_NOTIFICATION_STRATEGY_EXT:
- *params = mResetStrategy;
- break;
- case GL_NUM_SHADER_BINARY_FORMATS:
- *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
- break;
- case GL_SHADER_BINARY_FORMATS:
- std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
- break;
- case GL_NUM_PROGRAM_BINARY_FORMATS:
- *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
- break;
- case GL_PROGRAM_BINARY_FORMATS:
- std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
- break;
- case GL_NUM_EXTENSIONS:
- *params = static_cast<GLint>(mExtensionStrings.size());
- break;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
+ params);
+ break;
+ case GL_RESET_NOTIFICATION_STRATEGY_EXT:
+ *params = mResetStrategy;
+ break;
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
+ break;
+ case GL_SHADER_BINARY_FORMATS:
+ std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
+ break;
+ case GL_NUM_PROGRAM_BINARY_FORMATS:
+ *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
+ break;
+ case GL_PROGRAM_BINARY_FORMATS:
+ std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
+ break;
+ case GL_NUM_EXTENSIONS:
+ *params = static_cast<GLint>(mExtensionStrings.size());
+ break;
- // GL_KHR_debug
- case GL_MAX_DEBUG_MESSAGE_LENGTH:
- *params = mExtensions.maxDebugMessageLength;
- break;
- case GL_MAX_DEBUG_LOGGED_MESSAGES:
- *params = mExtensions.maxDebugLoggedMessages;
- break;
- case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
- *params = mExtensions.maxDebugGroupStackDepth;
- break;
- case GL_MAX_LABEL_LENGTH:
- *params = mExtensions.maxLabelLength;
- break;
-
- // GL_EXT_disjoint_timer_query
- case GL_GPU_DISJOINT_EXT:
- *params = mRenderer->getGPUDisjoint();
- break;
-
- default:
- mState.getIntegerv(getData(), pname, params);
- break;
+ // GL_KHR_debug
+ case GL_MAX_DEBUG_MESSAGE_LENGTH:
+ *params = mExtensions.maxDebugMessageLength;
+ break;
+ case GL_MAX_DEBUG_LOGGED_MESSAGES:
+ *params = mExtensions.maxDebugLoggedMessages;
+ break;
+ case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+ *params = mExtensions.maxDebugGroupStackDepth;
+ break;
+ case GL_MAX_LABEL_LENGTH:
+ *params = mExtensions.maxLabelLength;
+ break;
+
+ // GL_ANGLE_multiview
+ case GL_MAX_VIEWS_ANGLE:
+ *params = mExtensions.maxViews;
+ break;
+
+ // GL_EXT_disjoint_timer_query
+ case GL_GPU_DISJOINT_EXT:
+ *params = mImplementation->getGPUDisjoint();
+ break;
+ case GL_MAX_FRAMEBUFFER_WIDTH:
+ *params = mCaps.maxFramebufferWidth;
+ break;
+ case GL_MAX_FRAMEBUFFER_HEIGHT:
+ *params = mCaps.maxFramebufferHeight;
+ break;
+ case GL_MAX_FRAMEBUFFER_SAMPLES:
+ *params = mCaps.maxFramebufferSamples;
+ break;
+ case GL_MAX_SAMPLE_MASK_WORDS:
+ *params = mCaps.maxSampleMaskWords;
+ break;
+ case GL_MAX_COLOR_TEXTURE_SAMPLES:
+ *params = mCaps.maxColorTextureSamples;
+ break;
+ case GL_MAX_DEPTH_TEXTURE_SAMPLES:
+ *params = mCaps.maxDepthTextureSamples;
+ break;
+ case GL_MAX_INTEGER_SAMPLES:
+ *params = mCaps.maxIntegerSamples;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ *params = mCaps.maxVertexAttribRelativeOffset;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_BINDINGS:
+ *params = mCaps.maxVertexAttribBindings;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_STRIDE:
+ *params = mCaps.maxVertexAttribStride;
+ break;
+ case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
+ *params = mCaps.maxVertexAtomicCounterBuffers;
+ break;
+ case GL_MAX_VERTEX_ATOMIC_COUNTERS:
+ *params = mCaps.maxVertexAtomicCounters;
+ break;
+ case GL_MAX_VERTEX_IMAGE_UNIFORMS:
+ *params = mCaps.maxVertexImageUniforms;
+ break;
+ case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
+ *params = mCaps.maxVertexShaderStorageBlocks;
+ break;
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
+ *params = mCaps.maxFragmentAtomicCounterBuffers;
+ break;
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
+ *params = mCaps.maxFragmentAtomicCounters;
+ break;
+ case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
+ *params = mCaps.maxFragmentImageUniforms;
+ break;
+ case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
+ *params = mCaps.maxFragmentShaderStorageBlocks;
+ break;
+ case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
+ *params = mCaps.minProgramTextureGatherOffset;
+ break;
+ case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
+ *params = mCaps.maxProgramTextureGatherOffset;
+ break;
+ case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
+ *params = mCaps.maxComputeWorkGroupInvocations;
+ break;
+ case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
+ *params = mCaps.maxComputeUniformBlocks;
+ break;
+ case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
+ *params = mCaps.maxComputeTextureImageUnits;
+ break;
+ case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
+ *params = mCaps.maxComputeSharedMemorySize;
+ break;
+ case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
+ *params = mCaps.maxComputeUniformComponents;
+ break;
+ case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
+ *params = mCaps.maxComputeAtomicCounterBuffers;
+ break;
+ case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
+ *params = mCaps.maxComputeAtomicCounters;
+ break;
+ case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
+ *params = mCaps.maxComputeImageUniforms;
+ break;
+ case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
+ *params = mCaps.maxCombinedComputeUniformComponents;
+ break;
+ case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
+ *params = mCaps.maxComputeShaderStorageBlocks;
+ break;
+ case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
+ *params = mCaps.maxCombinedShaderOutputResources;
+ break;
+ case GL_MAX_UNIFORM_LOCATIONS:
+ *params = mCaps.maxUniformLocations;
+ break;
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
+ *params = mCaps.maxAtomicCounterBufferBindings;
+ break;
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
+ *params = mCaps.maxAtomicCounterBufferSize;
+ break;
+ case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
+ *params = mCaps.maxCombinedAtomicCounterBuffers;
+ break;
+ case GL_MAX_COMBINED_ATOMIC_COUNTERS:
+ *params = mCaps.maxCombinedAtomicCounters;
+ break;
+ case GL_MAX_IMAGE_UNITS:
+ *params = mCaps.maxImageUnits;
+ break;
+ case GL_MAX_COMBINED_IMAGE_UNIFORMS:
+ *params = mCaps.maxCombinedImageUniforms;
+ break;
+ case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
+ *params = mCaps.maxShaderStorageBufferBindings;
+ break;
+ case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
+ *params = mCaps.maxCombinedShaderStorageBlocks;
+ break;
+ case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
+ *params = mCaps.shaderStorageBufferOffsetAlignment;
+ break;
+ default:
+ mGLState.getIntegerv(this, pname, params);
+ break;
}
}
-void Context::getInteger64v(GLenum pname, GLint64 *params)
+void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
{
// Queries about context capabilities and maximums are answered by Context.
// Queries about current GL state values are answered by State.
switch (pname)
{
- case GL_MAX_ELEMENT_INDEX:
- *params = mCaps.maxElementIndex;
- break;
- case GL_MAX_UNIFORM_BLOCK_SIZE:
- *params = mCaps.maxUniformBlockSize;
- break;
- case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
- *params = mCaps.maxCombinedVertexUniformComponents;
- break;
- case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
- *params = mCaps.maxCombinedFragmentUniformComponents;
- break;
- case GL_MAX_SERVER_WAIT_TIMEOUT:
- *params = mCaps.maxServerWaitTimeout;
- break;
+ case GL_MAX_ELEMENT_INDEX:
+ *params = mCaps.maxElementIndex;
+ break;
+ case GL_MAX_UNIFORM_BLOCK_SIZE:
+ *params = mCaps.maxUniformBlockSize;
+ break;
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+ *params = mCaps.maxCombinedVertexUniformComponents;
+ break;
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+ *params = mCaps.maxCombinedFragmentUniformComponents;
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ *params = mCaps.maxServerWaitTimeout;
+ break;
- // GL_EXT_disjoint_timer_query
- case GL_TIMESTAMP_EXT:
- *params = mRenderer->getTimestamp();
- break;
- default:
- UNREACHABLE();
- break;
+ // GL_EXT_disjoint_timer_query
+ case GL_TIMESTAMP_EXT:
+ *params = mImplementation->getTimestamp();
+ break;
+
+ case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+ *params = mCaps.maxShaderStorageBlockSize;
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
void Context::getPointerv(GLenum pname, void **params) const
{
- mState.getPointerv(pname, params);
+ mGLState.getPointerv(pname, params);
}
-bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
+void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
{
// Queries about context capabilities and maximums are answered by Context.
// Queries about current GL state values are answered by State.
- // Indexed integer queries all refer to current state, so this function is a
- // mere passthrough.
- return mState.getIndexedIntegerv(target, index, data);
+
+ GLenum nativeType;
+ unsigned int numParams;
+ bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_INT)
+ {
+ switch (target)
+ {
+ case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+ ASSERT(index < 3u);
+ *data = mCaps.maxComputeWorkGroupCount[index];
+ break;
+ case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+ ASSERT(index < 3u);
+ *data = mCaps.maxComputeWorkGroupSize[index];
+ break;
+ default:
+ mGLState.getIntegeri_v(target, index, data);
+ }
+ }
+ else
+ {
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
+ }
}
-bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
+void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
{
// Queries about context capabilities and maximums are answered by Context.
// Queries about current GL state values are answered by State.
- // Indexed integer queries all refer to current state, so this function is a
- // mere passthrough.
- return mState.getIndexedInteger64v(target, index, data);
-}
-bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
-{
- if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ GLenum nativeType;
+ unsigned int numParams;
+ bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_INT_64_ANGLEX)
{
- *type = GL_INT;
- *numParams = 1;
- return true;
+ mGLState.getInteger64i_v(target, index, data);
}
-
- // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
- // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
- // to the fact that it is stored internally as a float, and so would require conversion
- // if returned from Context::getIntegerv. Since this conversion is already implemented
- // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
- // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
- // application.
- switch (pname)
+ else
{
- case GL_COMPRESSED_TEXTURE_FORMATS:
- {
- *type = GL_INT;
- *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
- }
- return true;
- case GL_PROGRAM_BINARY_FORMATS_OES:
- {
- *type = GL_INT;
- *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
- }
- return true;
- case GL_SHADER_BINARY_FORMATS:
- {
- *type = GL_INT;
- *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
- }
- return true;
-
- case GL_MAX_VERTEX_ATTRIBS:
- case GL_MAX_VERTEX_UNIFORM_VECTORS:
- case GL_MAX_VARYING_VECTORS:
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- case GL_MAX_TEXTURE_IMAGE_UNITS:
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
- case GL_MAX_RENDERBUFFER_SIZE:
- case GL_MAX_COLOR_ATTACHMENTS_EXT:
- case GL_MAX_DRAW_BUFFERS_EXT:
- case GL_NUM_SHADER_BINARY_FORMATS:
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
- case GL_ARRAY_BUFFER_BINDING:
- //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
- case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
- case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
- case GL_RENDERBUFFER_BINDING:
- case GL_CURRENT_PROGRAM:
- case GL_PACK_ALIGNMENT:
- case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
- case GL_UNPACK_ALIGNMENT:
- case GL_GENERATE_MIPMAP_HINT:
- case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
- case GL_RED_BITS:
- case GL_GREEN_BITS:
- case GL_BLUE_BITS:
- case GL_ALPHA_BITS:
- case GL_DEPTH_BITS:
- case GL_STENCIL_BITS:
- case GL_ELEMENT_ARRAY_BUFFER_BINDING:
- case GL_CULL_FACE_MODE:
- case GL_FRONT_FACE:
- case GL_ACTIVE_TEXTURE:
- case GL_STENCIL_FUNC:
- case GL_STENCIL_VALUE_MASK:
- case GL_STENCIL_REF:
- case GL_STENCIL_FAIL:
- case GL_STENCIL_PASS_DEPTH_FAIL:
- case GL_STENCIL_PASS_DEPTH_PASS:
- case GL_STENCIL_BACK_FUNC:
- case GL_STENCIL_BACK_VALUE_MASK:
- case GL_STENCIL_BACK_REF:
- case GL_STENCIL_BACK_FAIL:
- case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
- case GL_STENCIL_BACK_PASS_DEPTH_PASS:
- case GL_DEPTH_FUNC:
- case GL_BLEND_SRC_RGB:
- case GL_BLEND_SRC_ALPHA:
- case GL_BLEND_DST_RGB:
- case GL_BLEND_DST_ALPHA:
- case GL_BLEND_EQUATION_RGB:
- case GL_BLEND_EQUATION_ALPHA:
- case GL_STENCIL_WRITEMASK:
- case GL_STENCIL_BACK_WRITEMASK:
- case GL_STENCIL_CLEAR_VALUE:
- case GL_SUBPIXEL_BITS:
- case GL_MAX_TEXTURE_SIZE:
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
- case GL_SAMPLE_BUFFERS:
- case GL_SAMPLES:
- case GL_IMPLEMENTATION_COLOR_READ_TYPE:
- case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
- case GL_TEXTURE_BINDING_2D:
- case GL_TEXTURE_BINDING_CUBE_MAP:
- case GL_RESET_NOTIFICATION_STRATEGY_EXT:
- case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
- {
- *type = GL_INT;
- *numParams = 1;
- }
- return true;
- case GL_MAX_SAMPLES_ANGLE:
- {
- if (mExtensions.framebufferMultisample)
- {
- *type = GL_INT;
- *numParams = 1;
- }
- else
- {
- return false;
- }
- }
- return true;
- case GL_MAX_VIEWPORT_DIMS:
- {
- *type = GL_INT;
- *numParams = 2;
- }
- return true;
- case GL_VIEWPORT:
- case GL_SCISSOR_BOX:
- {
- *type = GL_INT;
- *numParams = 4;
- }
- return true;
- case GL_SHADER_COMPILER:
- case GL_SAMPLE_COVERAGE_INVERT:
- case GL_DEPTH_WRITEMASK:
- case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
- case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
- case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
- case GL_SAMPLE_COVERAGE:
- case GL_SCISSOR_TEST:
- case GL_STENCIL_TEST:
- case GL_DEPTH_TEST:
- case GL_BLEND:
- case GL_DITHER:
- case GL_CONTEXT_ROBUST_ACCESS_EXT:
- {
- *type = GL_BOOL;
- *numParams = 1;
- }
- return true;
- case GL_COLOR_WRITEMASK:
- {
- *type = GL_BOOL;
- *numParams = 4;
- }
- return true;
- case GL_POLYGON_OFFSET_FACTOR:
- case GL_POLYGON_OFFSET_UNITS:
- case GL_SAMPLE_COVERAGE_VALUE:
- case GL_DEPTH_CLEAR_VALUE:
- case GL_LINE_WIDTH:
- {
- *type = GL_FLOAT;
- *numParams = 1;
- }
- return true;
- case GL_ALIASED_LINE_WIDTH_RANGE:
- case GL_ALIASED_POINT_SIZE_RANGE:
- case GL_DEPTH_RANGE:
- {
- *type = GL_FLOAT;
- *numParams = 2;
- }
- return true;
- case GL_COLOR_CLEAR_VALUE:
- case GL_BLEND_COLOR:
- {
- *type = GL_FLOAT;
- *numParams = 4;
- }
- return true;
- case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!mExtensions.maxTextureAnisotropy)
- {
- return false;
- }
- *type = GL_FLOAT;
- *numParams = 1;
- return true;
- case GL_TIMESTAMP_EXT:
- if (!mExtensions.disjointTimerQuery)
- {
- return false;
- }
- *type = GL_INT_64_ANGLEX;
- *numParams = 1;
- return true;
- case GL_GPU_DISJOINT_EXT:
- if (!mExtensions.disjointTimerQuery)
- {
- return false;
- }
- *type = GL_INT;
- *numParams = 1;
- return true;
- }
-
- if (mExtensions.debug)
- {
- switch (pname)
- {
- case GL_DEBUG_LOGGED_MESSAGES:
- case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
- case GL_DEBUG_GROUP_STACK_DEPTH:
- case GL_MAX_DEBUG_MESSAGE_LENGTH:
- case GL_MAX_DEBUG_LOGGED_MESSAGES:
- case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
- case GL_MAX_LABEL_LENGTH:
- *type = GL_INT;
- *numParams = 1;
- return true;
-
- case GL_DEBUG_OUTPUT_SYNCHRONOUS:
- case GL_DEBUG_OUTPUT:
- *type = GL_BOOL;
- *numParams = 1;
- return true;
- }
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
}
+}
- // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
- switch (pname)
+void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
+{
+ // Queries about context capabilities and maximums are answered by Context.
+ // Queries about current GL state values are answered by State.
+
+ GLenum nativeType;
+ unsigned int numParams;
+ bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_BOOL)
{
- case GL_PACK_ROW_LENGTH:
- case GL_PACK_SKIP_ROWS:
- case GL_PACK_SKIP_PIXELS:
- if ((mClientVersion < 3) && !mExtensions.packSubimage)
- {
- return false;
- }
- *type = GL_INT;
- *numParams = 1;
- return true;
- case GL_UNPACK_ROW_LENGTH:
- case GL_UNPACK_SKIP_ROWS:
- case GL_UNPACK_SKIP_PIXELS:
- if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
- {
- return false;
- }
- *type = GL_INT;
- *numParams = 1;
- return true;
- case GL_VERTEX_ARRAY_BINDING:
- if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
- {
- return false;
- }
- *type = GL_INT;
- *numParams = 1;
- return true;
- case GL_PIXEL_PACK_BUFFER_BINDING:
- case GL_PIXEL_UNPACK_BUFFER_BINDING:
- if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
- {
- return false;
- }
- *type = GL_INT;
- *numParams = 1;
- return true;
+ mGLState.getBooleani_v(target, index, data);
}
-
- if (mClientVersion < 3)
+ else
{
- return false;
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
}
+}
- // Check for ES3.0+ parameter names
- switch (pname)
- {
- case GL_MAX_UNIFORM_BUFFER_BINDINGS:
- case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
- case GL_UNIFORM_BUFFER_BINDING:
- case GL_TRANSFORM_FEEDBACK_BINDING:
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- case GL_COPY_READ_BUFFER_BINDING:
- case GL_COPY_WRITE_BUFFER_BINDING:
- case GL_TEXTURE_BINDING_3D:
- case GL_TEXTURE_BINDING_2D_ARRAY:
- case GL_MAX_3D_TEXTURE_SIZE:
- case GL_MAX_ARRAY_TEXTURE_LAYERS:
- case GL_MAX_VERTEX_UNIFORM_BLOCKS:
- case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
- case GL_MAX_COMBINED_UNIFORM_BLOCKS:
- case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
- case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
- case GL_MAX_VARYING_COMPONENTS:
- case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
- case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
- case GL_MIN_PROGRAM_TEXEL_OFFSET:
- case GL_MAX_PROGRAM_TEXEL_OFFSET:
- case GL_NUM_EXTENSIONS:
- case GL_MAJOR_VERSION:
- case GL_MINOR_VERSION:
- case GL_MAX_ELEMENTS_INDICES:
- case GL_MAX_ELEMENTS_VERTICES:
- case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
- case GL_UNPACK_IMAGE_HEIGHT:
- case GL_UNPACK_SKIP_IMAGES:
- {
- *type = GL_INT;
- *numParams = 1;
- }
- return true;
+void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ QueryBufferParameteriv(buffer, pname, params);
+}
- case GL_MAX_ELEMENT_INDEX:
- case GL_MAX_UNIFORM_BLOCK_SIZE:
- case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
- case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
- case GL_MAX_SERVER_WAIT_TIMEOUT:
- {
- *type = GL_INT_64_ANGLEX;
- *numParams = 1;
- }
- return true;
+void Context::getFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+}
- case GL_TRANSFORM_FEEDBACK_ACTIVE:
- case GL_TRANSFORM_FEEDBACK_PAUSED:
- case GL_PRIMITIVE_RESTART_FIXED_INDEX:
- case GL_RASTERIZER_DISCARD:
- {
- *type = GL_BOOL;
- *numParams = 1;
- }
- return true;
+void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
+ QueryRenderbufferiv(this, renderbuffer, pname, params);
+}
- case GL_MAX_TEXTURE_LOD_BIAS:
- {
- *type = GL_FLOAT;
- *numParams = 1;
- }
- return true;
- }
+void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ Texture *texture = getTargetTexture(target);
+ QueryTexParameterfv(texture, pname, params);
+}
- return false;
+void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Texture *texture = getTargetTexture(target);
+ QueryTexParameteriv(texture, pname, params);
}
-bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
+void Context::getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
{
- if (mClientVersion < 3)
- {
- return false;
- }
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ QueryTexLevelParameteriv(texture, target, level, pname, params);
+}
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- case GL_UNIFORM_BUFFER_BINDING:
- {
- *type = GL_INT;
- *numParams = 1;
- }
- return true;
- case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- case GL_UNIFORM_BUFFER_START:
- case GL_UNIFORM_BUFFER_SIZE:
- {
- *type = GL_INT_64_ANGLEX;
- *numParams = 1;
- }
- }
+void Context::getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ QueryTexLevelParameterfv(texture, target, level, pname, params);
+}
- return false;
+void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ Texture *texture = getTargetTexture(target);
+ SetTexParameterf(this, texture, pname, param);
+ onTextureChange(texture);
+}
+
+void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ Texture *texture = getTargetTexture(target);
+ SetTexParameterfv(this, texture, pname, params);
+ onTextureChange(texture);
+}
+
+void Context::texParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Texture *texture = getTargetTexture(target);
+ SetTexParameteri(this, texture, pname, param);
+ onTextureChange(texture);
+}
+
+void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ Texture *texture = getTargetTexture(target);
+ SetTexParameteriv(this, texture, pname, params);
+ onTextureChange(texture);
+}
+
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
+ MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
+}
+
+void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
+ MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
+}
+
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
+}
+
+void Context::drawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instances)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
+}
+
+void Context::drawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
+}
+
+void Context::drawArraysIndirect(GLenum mode, const void *indirect)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
+}
+
+void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw());
+ ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
+}
+
+void Context::flush()
+{
+ handleError(mImplementation->flush(this));
+}
+
+void Context::finish()
+{
+ handleError(mImplementation->finish(this));
+}
+
+void Context::insertEventMarker(GLsizei length, const char *marker)
+{
+ ASSERT(mImplementation);
+ mImplementation->insertEventMarker(length, marker);
}
-Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
+void Context::pushGroupMarker(GLsizei length, const char *marker)
+{
+ ASSERT(mImplementation);
+ mImplementation->pushGroupMarker(length, marker);
+}
+
+void Context::popGroupMarker()
+{
+ ASSERT(mImplementation);
+ mImplementation->popGroupMarker();
+}
+
+void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+
+ programObject->bindUniformLocation(location, name);
+}
+
+void Context::setCoverageModulation(GLenum components)
+{
+ mGLState.setCoverageModulation(components);
+}
+
+void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
+{
+ mGLState.loadPathRenderingMatrix(matrixMode, matrix);
+}
+
+void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
+{
+ GLfloat I[16];
+ angle::Matrix<GLfloat>::setToIdentity(I);
+
+ mGLState.loadPathRenderingMatrix(matrixMode, I);
+}
+
+void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
- Error error = mRenderer->drawArrays(getData(), mode, first, count);
- if (error.isError())
- {
- return error;
- }
- MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
+ mImplementation->stencilFillPath(pathObj, fillMode, mask);
+}
+
+void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
+{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
- return Error(GL_NO_ERROR);
+ mImplementation->stencilStrokePath(pathObj, reference, mask);
}
-Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+void Context::coverFillPath(GLuint path, GLenum coverMode)
{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
- Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
- if (error.isError())
- {
- return error;
- }
- MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
+ mImplementation->coverFillPath(pathObj, coverMode);
+}
+
+void Context::coverStrokePath(GLuint path, GLenum coverMode)
+{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
- return Error(GL_NO_ERROR);
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->coverStrokePath(pathObj, coverMode);
}
-Error Context::drawElements(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- const IndexRange &indexRange)
+void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
- return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
+
+ mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
}
-Error Context::drawElementsInstanced(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- GLsizei instances,
- const IndexRange &indexRange)
+void Context::stencilThenCoverStrokePath(GLuint path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode)
{
+ const auto *pathObj = mState.mPaths->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
- return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
- indexRange);
+
+ mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
}
-Error Context::drawRangeElements(GLenum mode,
- GLuint start,
- GLuint end,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- const IndexRange &indexRange)
+void Context::coverFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
{
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
- return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
- indexRange);
+
+ mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
}
-Error Context::flush()
+void Context::coverStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
{
- return mRenderer->flush();
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
+ transformValues);
}
-Error Context::finish()
+void Context::stencilFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
{
- return mRenderer->finish();
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
+ transformValues);
}
-void Context::insertEventMarker(GLsizei length, const char *marker)
+void Context::stencilStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
{
- ASSERT(mRenderer);
- mRenderer->insertEventMarker(length, marker);
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
+ transformValues);
}
-void Context::pushGroupMarker(GLsizei length, const char *marker)
+void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
{
- ASSERT(mRenderer);
- mRenderer->pushGroupMarker(length, marker);
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
+ transformType, transformValues);
}
-void Context::popGroupMarker()
+void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
+ transformType, transformValues);
+}
+
+void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
+{
+ auto *programObject = getProgram(program);
+
+ programObject->bindFragmentInputLocation(location, name);
+}
+
+void Context::programPathFragmentInputGen(GLuint program,
+ GLint location,
+ GLenum genMode,
+ GLint components,
+ const GLfloat *coeffs)
+{
+ auto *programObject = getProgram(program);
+
+ programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
+}
+
+GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
+{
+ const auto *programObject = getProgram(program);
+ return QueryProgramResourceIndex(programObject, programInterface, name);
+}
+
+void Context::getProgramResourceName(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ const auto *programObject = getProgram(program);
+ QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
+}
+
+GLint Context::getProgramResourceLocation(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ const auto *programObject = getProgram(program);
+ return QueryProgramResourceLocation(programObject, programInterface, name);
+}
+
+void Context::getProgramResourceiv(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ const auto *programObject = getProgram(program);
+ QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
+ length, params);
+}
+
+void Context::getProgramInterfaceiv(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params)
{
- ASSERT(mRenderer);
- mRenderer->popGroupMarker();
+ const auto *programObject = getProgram(program);
+ QueryProgramInterfaceiv(programObject, programInterface, pname, params);
}
-void Context::recordError(const Error &error)
+void Context::handleError(const Error &error)
{
if (error.isError())
{
- mErrors.insert(error.getCode());
-
- if (!error.getMessage().empty())
+ GLenum code = error.getCode();
+ mErrors.insert(code);
+ if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
{
- auto &debug = mState.getDebug();
- debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
- GL_DEBUG_SEVERITY_HIGH, error.getMessage());
+ markContextLost();
}
+
+ ASSERT(!error.getMessage().empty());
+ mGLState.getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
+ GL_DEBUG_SEVERITY_HIGH, error.getMessage());
}
}
@@ -1636,32 +2093,61 @@ GLenum Context::getError()
}
}
+// NOTE: this function should not assume that this context is current!
+void Context::markContextLost()
+{
+ if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
+ {
+ mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
+ mContextLostForced = true;
+ }
+ mContextLost = true;
+}
+
+bool Context::isContextLost()
+{
+ return mContextLost;
+}
+
GLenum Context::getResetStatus()
{
- //TODO(jmadill): needs MANGLE reworking
- if (mResetStatus == GL_NO_ERROR && !mContextLost)
+ // Even if the application doesn't want to know about resets, we want to know
+ // as it will allow us to skip all the calls.
+ if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
{
- // mResetStatus will be set by the markContextLost callback
- // in the case a notification is sent
- if (mRenderer->testDeviceLost())
+ if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
{
- mRenderer->notifyDeviceLost();
+ mContextLost = true;
}
- }
- GLenum status = mResetStatus;
+ // EXT_robustness, section 2.6: If the reset notification behavior is
+ // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
+ // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
+ return GL_NO_ERROR;
+ }
- if (mResetStatus != GL_NO_ERROR)
+ // The GL_EXT_robustness spec says that if a reset is encountered, a reset
+ // status should be returned at least once, and GL_NO_ERROR should be returned
+ // once the device has finished resetting.
+ if (!mContextLost)
{
- ASSERT(mContextLost);
+ ASSERT(mResetStatus == GL_NO_ERROR);
+ mResetStatus = mImplementation->getResetStatus();
- if (mRenderer->testDeviceResettable())
+ if (mResetStatus != GL_NO_ERROR)
{
- mResetStatus = GL_NO_ERROR;
+ mContextLost = true;
}
}
+ else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
+ {
+ // If markContextLost was used to mark the context lost then
+ // assume that is not recoverable, and continue to report the
+ // lost reset status for the lifetime of this context.
+ mResetStatus = mImplementation->getResetStatus();
+ }
- return status;
+ return mResetStatus;
}
bool Context::isResetNotificationEnabled()
@@ -1681,73 +2167,57 @@ EGLenum Context::getClientType() const
EGLenum Context::getRenderBuffer() const
{
- auto framebufferIt = mFramebufferMap.find(0);
- if (framebufferIt != mFramebufferMap.end())
- {
- const Framebuffer *framebuffer = framebufferIt->second;
- const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
-
- ASSERT(backAttachment != nullptr);
- return backAttachment->getSurface()->getRenderBuffer();
- }
- else
+ const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
+ if (framebuffer == nullptr)
{
return EGL_NONE;
}
-}
-void Context::checkVertexArrayAllocation(GLuint vertexArray)
-{
- // Only called after a prior call to Gen.
- if (!getVertexArray(vertexArray))
- {
- VertexArray *vertexArrayObject =
- new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
- mVertexArrayMap[vertexArray] = vertexArrayObject;
- }
+ const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
+ ASSERT(backAttachment != nullptr);
+ return backAttachment->getSurface()->getRenderBuffer();
}
-void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
+VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
{
// Only called after a prior call to Gen.
- if (!getTransformFeedback(transformFeedback))
+ VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
+ if (!vertexArray)
{
- TransformFeedback *transformFeedbackObject =
- new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps);
- transformFeedbackObject->addRef();
- mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
+ vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
+ mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
+
+ mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
}
+
+ return vertexArray;
}
-Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
+TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
{
- // Can be called from Bind without a prior call to Gen.
- auto framebufferIt = mFramebufferMap.find(framebuffer);
- bool neverCreated = framebufferIt == mFramebufferMap.end();
- if (neverCreated || framebufferIt->second == nullptr)
+ // Only called after a prior call to Gen.
+ TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
+ if (!transformFeedback)
{
- Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
- if (neverCreated)
- {
- mFramebufferHandleAllocator.reserve(framebuffer);
- mFramebufferMap[framebuffer] = newFBO;
- return newFBO;
- }
-
- framebufferIt->second = newFBO;
+ transformFeedback =
+ new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
+ transformFeedback->addRef();
+ mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
}
- return framebufferIt->second;
+ return transformFeedback;
}
bool Context::isVertexArrayGenerated(GLuint vertexArray)
{
- return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
+ ASSERT(mVertexArrayMap.contains(0));
+ return mVertexArrayMap.contains(vertexArray);
}
bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
{
- return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
+ ASSERT(mTransformFeedbackMap.contains(0));
+ return mTransformFeedbackMap.contains(transformFeedback);
}
void Context::detachTexture(GLuint texture)
@@ -1756,7 +2226,7 @@ void Context::detachTexture(GLuint texture)
// allocation map management either here or in the resource manager at detach time.
// Zero textures are held by the Context, and we don't attempt to request them from
// the State.
- mState.detachTexture(mZeroTextures, texture);
+ mGLState.detachTexture(this, mZeroTextures, texture);
}
void Context::detachBuffer(GLuint buffer)
@@ -1769,7 +2239,7 @@ void Context::detachBuffer(GLuint buffer)
// Attachments to unbound container objects, such as
// deletion of a buffer attached to a vertex array object which is not bound to the context,
// are not affected and continue to act as references on the deleted object
- mState.detachBuffer(buffer);
+ mGLState.detachBuffer(this, buffer);
}
void Context::detachFramebuffer(GLuint framebuffer)
@@ -1779,15 +2249,16 @@ void Context::detachFramebuffer(GLuint framebuffer)
// to State at binding time.
// [OpenGL ES 2.0.24] section 4.4 page 107:
- // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
- // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
+ // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
+ // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
+ // zero.
- if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
+ if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
{
bindReadFramebuffer(0);
}
- if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
+ if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
{
bindDrawFramebuffer(0);
}
@@ -1795,7 +2266,7 @@ void Context::detachFramebuffer(GLuint framebuffer)
void Context::detachRenderbuffer(GLuint renderbuffer)
{
- mState.detachRenderbuffer(renderbuffer);
+ mGLState.detachRenderbuffer(this, renderbuffer);
}
void Context::detachVertexArray(GLuint vertexArray)
@@ -1807,7 +2278,7 @@ void Context::detachVertexArray(GLuint vertexArray)
// [OpenGL ES 3.0.2] section 2.10 page 43:
// If a vertex array object that is currently bound is deleted, the binding
// for that object reverts to zero and the default vertex array becomes current.
- if (mState.removeVertexArrayBinding(vertexArray))
+ if (mGLState.removeVertexArrayBinding(vertexArray))
{
bindVertexArray(0);
}
@@ -1815,151 +2286,188 @@ void Context::detachVertexArray(GLuint vertexArray)
void Context::detachTransformFeedback(GLuint transformFeedback)
{
- mState.detachTransformFeedback(transformFeedback);
+ // Transform feedback detachment is handled by Context, because 0 is a valid
+ // transform feedback, and a pointer to it must be passed from Context to State at
+ // binding time.
+
+ // The OpenGL specification doesn't mention what should happen when the currently bound
+ // transform feedback object is deleted. Since it is a container object, we treat it like
+ // VAOs and FBOs and set the current bound transform feedback back to 0.
+ if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
+ {
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+ }
}
void Context::detachSampler(GLuint sampler)
{
- mState.detachSampler(sampler);
+ mGLState.detachSampler(this, sampler);
}
-void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
+void Context::detachProgramPipeline(GLuint pipeline)
{
- mState.setVertexAttribDivisor(index, divisor);
+ mGLState.detachProgramPipeline(this, pipeline);
}
-void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
+void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
{
- mResourceManager->checkSamplerAllocation(sampler);
+ mGLState.setVertexAttribDivisor(this, index, divisor);
+}
- Sampler *samplerObject = getSampler(sampler);
- ASSERT(samplerObject);
+void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameteri(samplerObject, pname, param);
+ mGLState.setObjectDirty(GL_SAMPLER);
+}
- // clang-format off
- switch (pname)
- {
- case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
- case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
- case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
- case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
- case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
- default: UNREACHABLE(); break;
- }
- // clang-format on
+void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
+{
+ Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameteriv(samplerObject, pname, param);
+ mGLState.setObjectDirty(GL_SAMPLER);
}
void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
- mResourceManager->checkSamplerAllocation(sampler);
-
- Sampler *samplerObject = getSampler(sampler);
- ASSERT(samplerObject);
-
- // clang-format off
- switch (pname)
- {
- case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
- case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
- case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
- case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
- case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
- case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
- case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
- default: UNREACHABLE(); break;
- }
- // clang-format on
+ Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterf(samplerObject, pname, param);
+ mGLState.setObjectDirty(GL_SAMPLER);
}
-GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
+void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
{
- mResourceManager->checkSamplerAllocation(sampler);
-
- Sampler *samplerObject = getSampler(sampler);
- ASSERT(samplerObject);
-
- // clang-format off
- switch (pname)
- {
- case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
- case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
- case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
- case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
- case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
- case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
- case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
- case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
- case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
- default: UNREACHABLE(); return 0;
- }
- // clang-format on
+ Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterfv(samplerObject, pname, param);
+ mGLState.setObjectDirty(GL_SAMPLER);
}
-GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
+void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
{
- mResourceManager->checkSamplerAllocation(sampler);
+ const Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameteriv(samplerObject, pname, params);
+ mGLState.setObjectDirty(GL_SAMPLER);
+}
- Sampler *samplerObject = getSampler(sampler);
- ASSERT(samplerObject);
+void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
+{
+ const Sampler *samplerObject =
+ mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameterfv(samplerObject, pname, params);
+ mGLState.setObjectDirty(GL_SAMPLER);
+}
- // clang-format off
- switch (pname)
- {
- case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
- case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
- case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
- case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
- case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
- case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
- case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
- case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
- case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
- default: UNREACHABLE(); return 0;
- }
- // clang-format on
+void Context::programParameteri(GLuint program, GLenum pname, GLint value)
+{
+ gl::Program *programObject = getProgram(program);
+ SetProgramParameteri(programObject, pname, value);
}
void Context::initRendererString()
{
std::ostringstream rendererString;
rendererString << "ANGLE (";
- rendererString << mRenderer->getRendererDescription();
+ rendererString << mImplementation->getRendererDescription();
rendererString << ")";
mRendererString = MakeStaticString(rendererString.str());
}
-const std::string &Context::getRendererString() const
+void Context::initVersionStrings()
{
- return mRendererString;
+ const Version &clientVersion = getClientVersion();
+
+ std::ostringstream versionString;
+ versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
+ << ANGLE_VERSION_STRING << ")";
+ mVersionString = MakeStaticString(versionString.str());
+
+ std::ostringstream shadingLanguageVersionString;
+ shadingLanguageVersionString << "OpenGL ES GLSL ES "
+ << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
+ << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
+ << ")";
+ mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
}
void Context::initExtensionStrings()
{
- mExtensionStrings = mExtensions.getStrings();
+ auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
+ std::ostringstream combinedStringStream;
+ std::copy(strings.begin(), strings.end(),
+ std::ostream_iterator<const char *>(combinedStringStream, " "));
+ return MakeStaticString(combinedStringStream.str());
+ };
- std::ostringstream combinedStringStream;
- std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
- mExtensionString = combinedStringStream.str();
+ mExtensionStrings.clear();
+ for (const auto &extensionString : mExtensions.getStrings())
+ {
+ mExtensionStrings.push_back(MakeStaticString(extensionString));
+ }
+ mExtensionString = mergeExtensionStrings(mExtensionStrings);
+
+ const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
+
+ mRequestableExtensionStrings.clear();
+ for (const auto &extensionInfo : GetExtensionInfoMap())
+ {
+ if (extensionInfo.second.Requestable &&
+ !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
+ nativeExtensions.*(extensionInfo.second.ExtensionsMember))
+ {
+ mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
+ }
+ }
+ mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
}
-const std::string &Context::getExtensionString() const
+const GLubyte *Context::getString(GLenum name) const
{
- return mExtensionString;
+ switch (name)
+ {
+ case GL_VENDOR:
+ return reinterpret_cast<const GLubyte *>("Google Inc.");
+
+ case GL_RENDERER:
+ return reinterpret_cast<const GLubyte *>(mRendererString);
+
+ case GL_VERSION:
+ return reinterpret_cast<const GLubyte *>(mVersionString);
+
+ case GL_SHADING_LANGUAGE_VERSION:
+ return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
+
+ case GL_EXTENSIONS:
+ return reinterpret_cast<const GLubyte *>(mExtensionString);
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
}
-const std::string &Context::getExtensionString(size_t idx) const
+const GLubyte *Context::getStringi(GLenum name, GLuint index) const
{
- return mExtensionStrings[idx];
+ switch (name)
+ {
+ case GL_EXTENSIONS:
+ return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
}
size_t Context::getExtensionStringCount() const
@@ -1967,26 +2475,117 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size();
}
-void Context::initCaps(GLuint clientVersion)
+bool Context::isExtensionRequestable(const char *name)
+{
+ const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+ auto extension = extensionInfos.find(name);
+
+ const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
+ return extension != extensionInfos.end() && extension->second.Requestable &&
+ nativeExtensions.*(extension->second.ExtensionsMember);
+}
+
+void Context::requestExtension(const char *name)
+{
+ const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+ ASSERT(extensionInfos.find(name) != extensionInfos.end());
+ const auto &extension = extensionInfos.at(name);
+ ASSERT(extension.Requestable);
+ ASSERT(mImplementation->getNativeExtensions().*(extension.ExtensionsMember));
+
+ if (mExtensions.*(extension.ExtensionsMember))
+ {
+ // Extension already enabled
+ return;
+ }
+
+ mExtensions.*(extension.ExtensionsMember) = true;
+ updateCaps();
+ initExtensionStrings();
+
+ // Release the shader compiler so it will be re-created with the requested extensions enabled.
+ releaseShaderCompiler();
+
+ // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
+ // sampleable.
+ mState.mTextures->signalAllTexturesDirty();
+ for (auto &zeroTexture : mZeroTextures)
+ {
+ zeroTexture.second->signalDirty(InitState::Initialized);
+ }
+
+ mState.mFramebuffers->invalidateFramebufferComplenessCache();
+}
+
+size_t Context::getRequestableExtensionStringCount() const
+{
+ return mRequestableExtensionStrings.size();
+}
+
+void Context::beginTransformFeedback(GLenum primitiveMode)
+{
+ TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+ ASSERT(!transformFeedback->isPaused());
+
+ transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
+}
+
+bool Context::hasActiveTransformFeedback(GLuint program) const
+{
+ for (auto pair : mTransformFeedbackMap)
+ {
+ if (pair.second != nullptr && pair.second->hasBoundProgram(program))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
{
- mCaps = mRenderer->getRendererCaps();
+ mCaps = mImplementation->getNativeCaps();
- mExtensions = mRenderer->getRendererExtensions();
+ mExtensions = mImplementation->getNativeExtensions();
- mLimitations = mRenderer->getRendererLimitations();
+ mLimitations = mImplementation->getNativeLimitations();
- if (clientVersion < 3)
+ if (getClientVersion() < Version(3, 0))
{
// Disable ES3+ extensions
- mExtensions.colorBufferFloat = false;
+ mExtensions.colorBufferFloat = false;
+ mExtensions.eglImageExternalEssl3 = false;
+ mExtensions.textureNorm16 = false;
+ mExtensions.multiview = false;
+ mExtensions.maxViews = 1u;
}
- if (clientVersion > 2)
+ if (getClientVersion() < ES_3_1)
+ {
+ // Disable ES3.1+ extensions
+ mExtensions.geometryShader = false;
+ }
+
+ if (getClientVersion() > Version(2, 0))
{
// FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
- //mExtensions.sRGB = false;
+ // mExtensions.sRGB = false;
}
+ // Some extensions are always available because they are implemented in the GL layer.
+ mExtensions.bindUniformLocation = true;
+ mExtensions.vertexArrayObject = true;
+ mExtensions.bindGeneratesResource = true;
+ mExtensions.clientArrays = true;
+ mExtensions.requestExtension = true;
+
+ // Enable the no error extension if the context was created with the flag.
+ mExtensions.noError = mSkipValidation;
+
+ // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
+ mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
+
// Explicitly enable GL_KHR_debug
mExtensions.debug = true;
mExtensions.maxDebugMessageLength = 1024;
@@ -1994,64 +2593,186 @@ void Context::initCaps(GLuint clientVersion)
mExtensions.maxDebugGroupStackDepth = 1024;
mExtensions.maxLabelLength = 1024;
+ // Explicitly enable GL_ANGLE_robust_client_memory
+ mExtensions.robustClientMemory = true;
+
+ // Determine robust resource init availability from EGL.
+ mExtensions.robustResourceInitialization = robustResourceInit;
+
+ // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
+ // supports it.
+ mExtensions.robustBufferAccessBehavior =
+ mRobustAccess && mExtensions.robustBufferAccessBehavior;
+
+ // Enable the cache control query unconditionally.
+ mExtensions.programCacheControl = true;
+
// Apply implementation limits
- mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
- mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
- mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+ LimitCap(&mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
+
+ if (getClientVersion() < ES_3_1)
+ {
+ mCaps.maxVertexAttribBindings = mCaps.maxVertexAttributes;
+ }
+ else
+ {
+ LimitCap(&mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
+ }
- mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+ LimitCap(&mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+ LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+ LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
- mCaps.compressedTextureFormats.clear();
+ // Limit textures as well, so we can use fast bitsets with texture bindings.
+ LimitCap(&mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
+ LimitCap(&mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
+ LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
+
+ mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
- const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
- for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
+ // WebGL compatibility
+ mExtensions.webglCompatibility = mWebGLContext;
+ for (const auto &extensionInfo : GetExtensionInfoMap())
{
- GLenum format = i->first;
- TextureCaps formatCaps = i->second;
+ // If this context is for WebGL, disable all enableable extensions
+ if (mWebGLContext && extensionInfo.second.Requestable)
+ {
+ mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
+ }
+ }
+
+ // Generate texture caps
+ updateCaps();
+}
+
+void Context::updateCaps()
+{
+ mCaps.compressedTextureFormats.clear();
+ mTextureCaps.clear();
- const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+ for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
+ {
+ TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
// Update the format caps based on the client version and extensions.
// Caps are AND'd with the renderer caps because some core formats are still unsupported in
// ES3.
formatCaps.texturable =
- formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
+ formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
formatCaps.renderable =
- formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
+ formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
formatCaps.filterable =
- formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
+ formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
- // OpenGL ES does not support multisampling with integer formats
- if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
+ // OpenGL ES does not support multisampling with non-rendererable formats
+ // OpenGL ES 3.0 or prior does not support multisampling with integer formats
+ if (!formatCaps.renderable ||
+ (getClientVersion() < ES_3_1 &&
+ (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
{
formatCaps.sampleCounts.clear();
}
+ else
+ {
+ // We may have limited the max samples for some required renderbuffer formats due to
+ // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
+ GLuint formatMaxSamples = formatCaps.getMaxSamples();
+
+ // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
+ // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
+ // exception of signed and unsigned integer formats."
+ if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
+ formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
+ {
+ ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
+ mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
+ }
+
+ // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
+ if (getClientVersion() >= ES_3_1)
+ {
+ // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
+ // in these required formats with up to the value of MAX_SAMPLES multisamples, with
+ // the exception that the signed and unsigned integer formats are required only to
+ // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
+ // multisamples, which must be at least one."
+ if (formatInfo.componentType == GL_INT ||
+ formatInfo.componentType == GL_UNSIGNED_INT)
+ {
+ mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
+ }
+
+ // GLES 3.1 section 19.3.1.
+ if (formatCaps.texturable)
+ {
+ if (formatInfo.depthBits > 0)
+ {
+ mCaps.maxDepthTextureSamples =
+ std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
+ }
+ else if (formatInfo.redBits > 0)
+ {
+ mCaps.maxColorTextureSamples =
+ std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
+ }
+ }
+ }
+ }
if (formatCaps.texturable && formatInfo.compressed)
{
- mCaps.compressedTextureFormats.push_back(format);
+ mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
}
- mTextureCaps.insert(format, formatCaps);
+ mTextureCaps.insert(sizedInternalFormat, formatCaps);
+ }
+
+ // If program binary is disabled, blank out the memory cache pointer.
+ if (!mImplementation->getNativeExtensions().getProgramBinary)
+ {
+ mMemoryProgramCache = nullptr;
}
}
-void Context::syncRendererState()
+void Context::initWorkarounds()
+{
+ // Apply back-end workarounds.
+ mImplementation->applyNativeWorkarounds(&mWorkarounds);
+
+ // Lose the context upon out of memory error if the application is
+ // expecting to watch for those events.
+ mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
+}
+
+Error Context::prepareForDraw()
{
- const State::DirtyBits &dirtyBits = mState.getDirtyBits();
- mRenderer->syncState(mState, dirtyBits);
- mState.clearDirtyBits();
- mState.syncDirtyObjects();
+ syncRendererState();
+
+ if (isRobustResourceInitEnabled())
+ {
+ ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
+ ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
+ }
+
+ return NoError();
}
-void Context::syncRendererState(const State::DirtyBits &bitMask)
+void Context::syncRendererState()
{
- const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
- mRenderer->syncState(mState, dirtyBits);
- mState.clearDirtyBits(dirtyBits);
+ mGLState.syncDirtyObjects(this);
+ const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
+ mImplementation->syncState(this, dirtyBits);
+ mGLState.clearDirtyBits();
+}
- // TODO(jmadill): Filter objects by bitMask somehow?
- mState.syncDirtyObjects();
+void Context::syncRendererState(const State::DirtyBits &bitMask,
+ const State::DirtyObjects &objectMask)
+{
+ mGLState.syncDirtyObjects(this, objectMask);
+ const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
+ mImplementation->syncState(this, dirtyBits);
+ mGLState.clearDirtyBits(dirtyBits);
}
void Context::blitFramebuffer(GLint srcX0,
@@ -2065,76 +2786,44 @@ void Context::blitFramebuffer(GLint srcX0,
GLbitfield mask,
GLenum filter)
{
- Framebuffer *readFramebuffer = mState.getReadFramebuffer();
- ASSERT(readFramebuffer);
-
- Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
+ Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
ASSERT(drawFramebuffer);
Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
- syncRendererState(mState.blitStateBitMask());
+ syncStateForBlit();
- Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
- if (error.isError())
- {
- recordError(error);
- return;
- }
+ handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
}
void Context::clear(GLbitfield mask)
{
- // Sync the clear state
- syncRendererState(mState.clearStateBitMask());
-
- Error error = mState.getDrawFramebuffer()->clear(mData, mask);
- if (error.isError())
- {
- recordError(error);
- }
+ syncStateForClear();
+ handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
}
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
- // Sync the clear state
- syncRendererState(mState.clearStateBitMask());
-
- Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
- if (error.isError())
- {
- recordError(error);
- }
+ syncStateForClear();
+ handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
}
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
- // Sync the clear state
- syncRendererState(mState.clearStateBitMask());
-
- Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
- if (error.isError())
- {
- recordError(error);
- }
+ syncStateForClear();
+ handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
}
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
- // Sync the clear state
- syncRendererState(mState.clearStateBitMask());
-
- Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
- if (error.isError())
- {
- recordError(error);
- }
+ syncStateForClear();
+ handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
}
void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+ Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
ASSERT(framebufferObject);
// If a buffer is not present, the clear has no effect
@@ -2144,14 +2833,8 @@ void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLin
return;
}
- // Sync the clear state
- syncRendererState(mState.clearStateBitMask());
-
- Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
- if (error.isError())
- {
- recordError(error);
- }
+ syncStateForClear();
+ handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
}
void Context::readPixels(GLint x,
@@ -2160,20 +2843,20 @@ void Context::readPixels(GLint x,
GLsizei height,
GLenum format,
GLenum type,
- GLvoid *pixels)
+ void *pixels)
{
- // Sync pack state
- syncRendererState(mState.packStateBitMask());
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
- Framebuffer *framebufferObject = mState.getReadFramebuffer();
- ASSERT(framebufferObject);
+ syncStateForReadPixels();
+
+ Framebuffer *readFBO = mGLState.getReadFramebuffer();
+ ASSERT(readFBO);
Rectangle area(x, y, width, height);
- Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
- if (error.isError())
- {
- recordError(error);
- }
+ handleError(readFBO->readPixels(this, area, format, type, pixels));
}
void Context::copyTexImage2D(GLenum target,
@@ -2186,18 +2869,14 @@ void Context::copyTexImage2D(GLenum target,
GLint border)
{
// Only sync the read FBO
- mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
+ mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Texture *texture =
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
- if (error.isError())
- {
- recordError(error);
- }
+ handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
}
void Context::copyTexSubImage2D(GLenum target,
@@ -2209,20 +2888,21 @@ void Context::copyTexSubImage2D(GLenum target,
GLsizei width,
GLsizei height)
{
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
// Only sync the read FBO
- mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
+ mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Offset destOffset(xoffset, yoffset, 0);
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Texture *texture =
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
- if (error.isError())
- {
- recordError(error);
- }
+ handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
}
void Context::copyTexSubImage3D(GLenum target,
@@ -2235,19 +2915,20 @@ void Context::copyTexSubImage3D(GLenum target,
GLsizei width,
GLsizei height)
{
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
// Only sync the read FBO
- mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
+ mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Offset destOffset(xoffset, yoffset, zoffset);
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mState.getReadFramebuffer();
- Texture *texture = getTargetTexture(target);
- Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
- if (error.isError())
- {
- recordError(error);
- }
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
}
void Context::framebufferTexture2D(GLenum target,
@@ -2256,7 +2937,7 @@ void Context::framebufferTexture2D(GLenum target,
GLuint texture,
GLint level)
{
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
if (texture != 0)
@@ -2269,20 +2950,29 @@ void Context::framebufferTexture2D(GLenum target,
{
index = ImageIndex::Make2D(level);
}
+ else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
+ {
+ index = ImageIndex::MakeRectangle(level);
+ }
+ else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
+ {
+ ASSERT(level == 0);
+ index = ImageIndex::Make2DMultisample();
+ }
else
{
ASSERT(IsCubeMapTextureTarget(textarget));
index = ImageIndex::MakeCube(textarget, level);
}
- framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
}
else
{
- framebuffer->resetAttachment(attachment);
+ framebuffer->resetAttachment(this, attachment);
}
- mState.setObjectDirty(target);
+ mGLState.setObjectDirty(target);
}
void Context::framebufferRenderbuffer(GLenum target,
@@ -2290,21 +2980,22 @@ void Context::framebufferRenderbuffer(GLenum target,
GLenum renderbuffertarget,
GLuint renderbuffer)
{
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
if (renderbuffer != 0)
{
Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
- framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
+
+ framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
renderbufferObject);
}
else
{
- framebuffer->resetAttachment(attachment);
+ framebuffer->resetAttachment(this, attachment);
}
- mState.setObjectDirty(target);
+ mGLState.setObjectDirty(target);
}
void Context::framebufferTextureLayer(GLenum target,
@@ -2313,7 +3004,7 @@ void Context::framebufferTextureLayer(GLenum target,
GLint level,
GLint layer)
{
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
if (texture != 0)
@@ -2332,46 +3023,94 @@ void Context::framebufferTextureLayer(GLenum target,
index = ImageIndex::Make2DArray(level, layer);
}
- framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mGLState.setObjectDirty(target);
+}
+
+void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews)
+{
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+
+ ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
+ framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
+ numViews, baseViewIndex);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mGLState.setObjectDirty(target);
+}
+
+void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLsizei numViews,
+ const GLint *viewportOffsets)
+{
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+
+ ImageIndex index = ImageIndex::Make2D(level);
+ framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
+ textureObj, numViews, viewportOffsets);
}
else
{
- framebuffer->resetAttachment(attachment);
+ framebuffer->resetAttachment(this, attachment);
}
- mState.setObjectDirty(target);
+ mGLState.setObjectDirty(target);
}
void Context::drawBuffers(GLsizei n, const GLenum *bufs)
{
- Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
ASSERT(framebuffer);
framebuffer->setDrawBuffers(n, bufs);
- mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
+ mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
}
void Context::readBuffer(GLenum mode)
{
- Framebuffer *readFBO = mState.getReadFramebuffer();
+ Framebuffer *readFBO = mGLState.getReadFramebuffer();
readFBO->setReadBuffer(mode);
- mState.setObjectDirty(GL_READ_FRAMEBUFFER);
+ mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
}
void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
{
// Only sync the FBO
- mState.syncDirtyObject(target);
+ mGLState.syncDirtyObject(this, target);
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
// The specification isn't clear what should be done when the framebuffer isn't complete.
// We leave it up to the framebuffer implementation to decide what to do.
- Error error = framebuffer->discard(numAttachments, attachments);
- if (error.isError())
- {
- recordError(error);
- }
+ handleError(framebuffer->discard(this, numAttachments, attachments));
}
void Context::invalidateFramebuffer(GLenum target,
@@ -2379,20 +3118,17 @@ void Context::invalidateFramebuffer(GLenum target,
const GLenum *attachments)
{
// Only sync the FBO
- mState.syncDirtyObject(target);
+ mGLState.syncDirtyObject(this, target);
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
- if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
{
- Error error = framebuffer->invalidate(numAttachments, attachments);
- if (error.isError())
- {
- recordError(error);
- return;
- }
+ return;
}
+
+ handleError(framebuffer->invalidate(this, numAttachments, attachments));
}
void Context::invalidateSubFramebuffer(GLenum target,
@@ -2404,21 +3140,2419 @@ void Context::invalidateSubFramebuffer(GLenum target,
GLsizei height)
{
// Only sync the FBO
- mState.syncDirtyObject(target);
+ mGLState.syncDirtyObject(this, target);
- Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer);
- if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return;
+ }
+
+ Rectangle area(x, y, width, height);
+ handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
+}
+
+void Context::texImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ syncStateForTexImage();
+
+ Extents size(width, height, 1);
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
+ size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texImage3D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ syncStateForTexImage();
+
+ Extents size(width, height, depth);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
+ size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ syncStateForTexImage();
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
+ type, reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0 || depth == 0)
+ {
+ return;
+ }
+
+ syncStateForTexImage();
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
+ type, reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::compressedTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ syncStateForTexImage();
+
+ Extents size(width, height, 1);
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
+ internalformat, size, imageSize,
+ reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexImage3D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ syncStateForTexImage();
+
+ Extents size(width, height, depth);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
+ internalformat, size, imageSize,
+ reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ syncStateForTexImage();
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture =
+ getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
+ format, imageSize,
+ reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ syncStateForTexImage();
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
+ format, imageSize,
+ reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::generateMipmap(GLenum target)
+{
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->generateMipmap(this));
+}
+
+void Context::copyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ syncStateForTexImage();
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ handleError(destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType,
+ sourceLevel, ConvertToBool(unpackFlipY),
+ ConvertToBool(unpackPremultiplyAlpha),
+ ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
+}
+
+void Context::copySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ // Zero sized copies are valid but no-ops
+ if (width == 0 || height == 0)
{
- Rectangle area(x, y, width, height);
- Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
- if (error.isError())
+ return;
+ }
+
+ syncStateForTexImage();
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ Offset offset(xoffset, yoffset, 0);
+ Rectangle area(x, y, width, height);
+ handleError(destTexture->copySubTexture(this, destTarget, destLevel, offset, sourceLevel, area,
+ ConvertToBool(unpackFlipY),
+ ConvertToBool(unpackPremultiplyAlpha),
+ ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
+}
+
+void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
+{
+ syncStateForTexImage();
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ handleError(destTexture->copyCompressedTexture(this, sourceTexture));
+}
+
+void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ QueryBufferPointerv(buffer, pname, params);
+}
+
+void *Context::mapBuffer(BufferBinding target, GLenum access)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ Error error = buffer->map(this, access);
+ if (error.isError())
+ {
+ handleError(error);
+ return nullptr;
+ }
+
+ return buffer->getMapPointer();
+}
+
+GLboolean Context::unmapBuffer(BufferBinding target)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ GLboolean result;
+ Error error = buffer->unmap(this, &result);
+ if (error.isError())
+ {
+ handleError(error);
+ return GL_FALSE;
+ }
+
+ return result;
+}
+
+void *Context::mapBufferRange(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ Error error = buffer->mapRange(this, offset, length, access);
+ if (error.isError())
+ {
+ handleError(error);
+ return nullptr;
+ }
+
+ return buffer->getMapPointer();
+}
+
+void Context::flushMappedBufferRange(BufferBinding /*target*/,
+ GLintptr /*offset*/,
+ GLsizeiptr /*length*/)
+{
+ // We do not currently support a non-trivial implementation of FlushMappedBufferRange
+}
+
+void Context::syncStateForReadPixels()
+{
+ syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
+}
+
+void Context::syncStateForTexImage()
+{
+ syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
+}
+
+void Context::syncStateForClear()
+{
+ syncRendererState(mClearDirtyBits, mClearDirtyObjects);
+}
+
+void Context::syncStateForBlit()
+{
+ syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
+}
+
+void Context::activeShaderProgram(GLuint pipeline, GLuint program)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::activeTexture(GLenum texture)
+{
+ mGLState.setActiveSampler(texture - GL_TEXTURE0);
+}
+
+void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
+}
+
+void Context::blendEquation(GLenum mode)
+{
+ mGLState.setBlendEquation(mode, mode);
+}
+
+void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ mGLState.setBlendEquation(modeRGB, modeAlpha);
+}
+
+void Context::blendFunc(GLenum sfactor, GLenum dfactor)
+{
+ mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
+}
+
+void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ mGLState.setColorClearValue(red, green, blue, alpha);
+}
+
+void Context::clearDepthf(GLfloat depth)
+{
+ mGLState.setDepthClearValue(depth);
+}
+
+void Context::clearStencil(GLint s)
+{
+ mGLState.setStencilClearValue(s);
+}
+
+void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ mGLState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
+ ConvertToBool(alpha));
+}
+
+void Context::cullFace(CullFaceMode mode)
+{
+ mGLState.setCullMode(mode);
+}
+
+void Context::depthFunc(GLenum func)
+{
+ mGLState.setDepthFunc(func);
+}
+
+void Context::depthMask(GLboolean flag)
+{
+ mGLState.setDepthMask(ConvertToBool(flag));
+}
+
+void Context::depthRangef(GLfloat zNear, GLfloat zFar)
+{
+ mGLState.setDepthRange(zNear, zFar);
+}
+
+void Context::disable(GLenum cap)
+{
+ mGLState.setEnableFeature(cap, false);
+}
+
+void Context::disableVertexAttribArray(GLuint index)
+{
+ mGLState.setEnableVertexAttribArray(index, false);
+}
+
+void Context::enable(GLenum cap)
+{
+ mGLState.setEnableFeature(cap, true);
+}
+
+void Context::enableVertexAttribArray(GLuint index)
+{
+ mGLState.setEnableVertexAttribArray(index, true);
+}
+
+void Context::frontFace(GLenum mode)
+{
+ mGLState.setFrontFace(mode);
+}
+
+void Context::hint(GLenum target, GLenum mode)
+{
+ switch (target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ mGLState.setGenerateMipmapHint(mode);
+ break;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ mGLState.setFragmentShaderDerivativeHint(mode);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::lineWidth(GLfloat width)
+{
+ mGLState.setLineWidth(width);
+}
+
+void Context::pixelStorei(GLenum pname, GLint param)
+{
+ switch (pname)
+ {
+ case GL_UNPACK_ALIGNMENT:
+ mGLState.setUnpackAlignment(param);
+ break;
+
+ case GL_PACK_ALIGNMENT:
+ mGLState.setPackAlignment(param);
+ break;
+
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ mGLState.setPackReverseRowOrder(param != 0);
+ break;
+
+ case GL_UNPACK_ROW_LENGTH:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
+ mGLState.setUnpackRowLength(param);
+ break;
+
+ case GL_UNPACK_IMAGE_HEIGHT:
+ ASSERT(getClientMajorVersion() >= 3);
+ mGLState.setUnpackImageHeight(param);
+ break;
+
+ case GL_UNPACK_SKIP_IMAGES:
+ ASSERT(getClientMajorVersion() >= 3);
+ mGLState.setUnpackSkipImages(param);
+ break;
+
+ case GL_UNPACK_SKIP_ROWS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
+ mGLState.setUnpackSkipRows(param);
+ break;
+
+ case GL_UNPACK_SKIP_PIXELS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
+ mGLState.setUnpackSkipPixels(param);
+ break;
+
+ case GL_PACK_ROW_LENGTH:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
+ mGLState.setPackRowLength(param);
+ break;
+
+ case GL_PACK_SKIP_ROWS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
+ mGLState.setPackSkipRows(param);
+ break;
+
+ case GL_PACK_SKIP_PIXELS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
+ mGLState.setPackSkipPixels(param);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::polygonOffset(GLfloat factor, GLfloat units)
+{
+ mGLState.setPolygonOffsetParams(factor, units);
+}
+
+void Context::sampleCoverage(GLfloat value, GLboolean invert)
+{
+ mGLState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
+}
+
+void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ mGLState.setSampleMaskParams(maskNumber, mask);
+}
+
+void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ mGLState.setScissorParams(x, y, width, height);
+}
+
+void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilParams(func, ref, mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilBackParams(func, ref, mask);
+ }
+}
+
+void Context::stencilMaskSeparate(GLenum face, GLuint mask)
+{
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilWritemask(mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilBackWritemask(mask);
+ }
+}
+
+void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilOperations(fail, zfail, zpass);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mGLState.setStencilBackOperations(fail, zfail, zpass);
+ }
+}
+
+void Context::vertexAttrib1f(GLuint index, GLfloat x)
+{
+ GLfloat vals[4] = {x, 0, 0, 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], 0, 0, 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ GLfloat vals[4] = {x, y, 0, 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], values[1], 0, 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat vals[4] = {x, y, z, 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], values[1], values[2], 1};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat vals[4] = {x, y, z, w};
+ mGLState.setVertexAttribf(index, vals);
+}
+
+void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
+{
+ mGLState.setVertexAttribf(index, values);
+}
+
+void Context::vertexAttribPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr)
+{
+ mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+ size, type, ConvertToBool(normalized), false, stride, ptr);
+}
+
+void Context::vertexAttribFormat(GLuint attribIndex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeOffset)
+{
+ mGLState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
+ relativeOffset);
+}
+
+void Context::vertexAttribIFormat(GLuint attribIndex,
+ GLint size,
+ GLenum type,
+ GLuint relativeOffset)
+{
+ mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
+}
+
+void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
+{
+ mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
+}
+
+void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
+{
+ mGLState.setVertexBindingDivisor(bindingIndex, divisor);
+}
+
+void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ mGLState.setViewportParams(x, y, width, height);
+}
+
+void Context::vertexAttribIPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+ size, type, false, true, stride, pointer);
+}
+
+void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ GLint vals[4] = {x, y, z, w};
+ mGLState.setVertexAttribi(index, vals);
+}
+
+void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ GLuint vals[4] = {x, y, z, w};
+ mGLState.setVertexAttribu(index, vals);
+}
+
+void Context::vertexAttribI4iv(GLuint index, const GLint *v)
+{
+ mGLState.setVertexAttribi(index, v);
+}
+
+void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+ mGLState.setVertexAttribu(index, v);
+}
+
+void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getGLState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getGLState().getVertexArray();
+ QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getGLState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getGLState().getVertexArray();
+ QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getGLState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getGLState().getVertexArray();
+ QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getGLState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getGLState().getVertexArray();
+ QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
+{
+ const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
+ QueryVertexAttribPointerv(attrib, pname, pointer);
+}
+
+void Context::debugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ std::vector<GLuint> idVector(ids, ids + count);
+ mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
+ ConvertToBool(enabled));
+}
+
+void Context::debugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
+ mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
+}
+
+void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
+{
+ mGLState.getDebug().setCallback(callback, userParam);
+}
+
+GLuint Context::getDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
+ severities, lengths, messageLog));
+}
+
+void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
+{
+ std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
+ mGLState.getDebug().pushGroup(source, id, std::move(msg));
+ mImplementation->pushDebugGroup(source, id, length, message);
+}
+
+void Context::popDebugGroup()
+{
+ mGLState.getDebug().popGroup();
+ mImplementation->popDebugGroup();
+}
+
+void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+ handleError(buffer->bufferData(this, target, data, size, usage));
+}
+
+void Context::bufferSubData(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ if (data == nullptr)
+ {
+ return;
+ }
+
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ ASSERT(buffer);
+ handleError(buffer->bufferSubData(this, target, data, size, offset));
+}
+
+void Context::attachShader(GLuint program, GLuint shader)
+{
+ Program *programObject = mState.mShaderPrograms->getProgram(program);
+ Shader *shaderObject = mState.mShaderPrograms->getShader(shader);
+ ASSERT(programObject && shaderObject);
+ programObject->attachShader(shaderObject);
+}
+
+const Workarounds &Context::getWorkarounds() const
+{
+ return mWorkarounds;
+}
+
+void Context::copyBufferSubData(BufferBinding readTarget,
+ BufferBinding writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ // if size is zero, the copy is a successful no-op
+ if (size == 0)
+ {
+ return;
+ }
+
+ // TODO(jmadill): cache these.
+ Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
+ Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
+
+ handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
+}
+
+void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ // TODO(jmadill): Re-use this from the validation if possible.
+ ASSERT(programObject);
+ programObject->bindAttributeLocation(index, name);
+}
+
+void Context::bindBuffer(BufferBinding target, GLuint buffer)
+{
+ Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+ mGLState.setBufferBinding(this, target, bufferObject);
+}
+
+void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer)
+{
+ bindBufferRange(target, index, buffer, 0, 0);
+}
+
+void Context::bindBufferRange(BufferBinding target,
+ GLuint index,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+ mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size);
+}
+
+void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
+ {
+ bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
+ {
+ bindDrawFramebuffer(framebuffer);
+ }
+}
+
+void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ ASSERT(target == GL_RENDERBUFFER);
+ Renderbuffer *object =
+ mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
+ mGLState.setRenderbufferBinding(this, object);
+}
+
+void Context::texStorage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ Extents size(width, height, 1);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
+ ConvertToBool(fixedsamplelocations)));
+}
+
+void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
+{
+ // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
+ // the sample position should be queried by DRAW_FRAMEBUFFER.
+ mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
+ const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
+
+ switch (pname)
+ {
+ case GL_SAMPLE_POSITION:
+ handleError(framebuffer->getSamplePosition(index, val));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Context::renderbufferStorage(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
+
+ Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
+ handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
+}
+
+void Context::renderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
+
+ Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
+ handleError(
+ renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
+}
+
+void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
+{
+ const Sync *syncObject = getSync(sync);
+ handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
+}
+
+void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ QueryFramebufferParameteriv(framebuffer, pname, params);
+}
+
+void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ SetFramebufferParameteri(framebuffer, pname, param);
+}
+
+Error Context::getScratchBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **scratchBufferOut) const
+{
+ if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
+ {
+ return OutOfMemory() << "Failed to allocate internal buffer.";
+ }
+ return NoError();
+}
+
+Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **zeroBufferOut) const
+{
+ if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
+ {
+ return OutOfMemory() << "Failed to allocate internal buffer.";
+ }
+ return NoError();
+}
+
+void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
+{
+ if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
+ {
+ return;
+ }
+
+ // TODO(jmadill): Dirty bits for compute.
+ if (isRobustResourceInitEnabled())
+ {
+ ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
+ }
+
+ handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
+}
+
+void Context::dispatchComputeIndirect(GLintptr indirect)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texStorage2D(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height)
+{
+ Extents size(width, height, 1);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setStorage(this, target, levels, internalFormat, size));
+}
+
+void Context::texStorage3D(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ Extents size(width, height, depth);
+ Texture *texture = getTargetTexture(target);
+ handleError(texture->setStorage(this, target, levels, internalFormat, size));
+}
+
+void Context::memoryBarrier(GLbitfield barriers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::memoryBarrierByRegion(GLbitfield barriers)
+{
+ UNIMPLEMENTED();
+}
+
+GLenum Context::checkFramebufferStatus(GLenum target)
+{
+ Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ return framebuffer->checkStatus(this);
+}
+
+void Context::compileShader(GLuint shader)
+{
+ Shader *shaderObject = GetValidShader(this, shader);
+ if (!shaderObject)
+ {
+ return;
+ }
+ shaderObject->compile(this);
+}
+
+void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteBuffer(buffers[i]);
+ }
+}
+
+void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (framebuffers[i] != 0)
+ {
+ deleteFramebuffer(framebuffers[i]);
+ }
+ }
+}
+
+void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteRenderbuffer(renderbuffers[i]);
+ }
+}
+
+void Context::deleteTextures(GLsizei n, const GLuint *textures)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (textures[i] != 0)
{
- recordError(error);
+ deleteTexture(textures[i]);
+ }
+ }
+}
+
+void Context::detachShader(GLuint program, GLuint shader)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+
+ programObject->detachShader(this, shaderObject);
+}
+
+void Context::genBuffers(GLsizei n, GLuint *buffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ buffers[i] = createBuffer();
+ }
+}
+
+void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ framebuffers[i] = createFramebuffer();
+ }
+}
+
+void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ renderbuffers[i] = createRenderbuffer();
+ }
+}
+
+void Context::genTextures(GLsizei n, GLuint *textures)
+{
+ for (int i = 0; i < n; i++)
+ {
+ textures[i] = createTexture();
+ }
+}
+
+void Context::getActiveAttrib(GLuint program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getActiveAttribute(index, bufsize, length, size, type, name);
+}
+
+void Context::getActiveUniform(GLuint program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getActiveUniform(index, bufsize, length, size, type, name);
+}
+
+void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getAttachedShaders(maxcount, count, shaders);
+}
+
+GLint Context::getAttribLocation(GLuint program, const GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ return programObject->getAttributeLocation(name);
+}
+
+void Context::getBooleanv(GLenum pname, GLboolean *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_BOOL)
+ {
+ getBooleanvImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getFloatv(GLenum pname, GLfloat *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_FLOAT)
+ {
+ getFloatvImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getIntegerv(GLenum pname, GLint *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_INT)
+ {
+ getIntegervImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ QueryProgramiv(this, programObject, pname, params);
+}
+
+void Context::getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getInfoLog(bufsize, length, infolog);
+}
+
+void Context::getProgramPipelineInfoLog(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ QueryShaderiv(this, shaderObject, pname, params);
+}
+
+void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->getInfoLog(this, bufsize, length, infolog);
+}
+
+void Context::getShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision)
+{
+ // TODO(jmadill): Compute shaders.
+
+ switch (shadertype)
+ {
+ case GL_VERTEX_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ mCaps.vertexLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ mCaps.vertexMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ mCaps.vertexHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ mCaps.vertexLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ mCaps.vertexMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ mCaps.vertexHighpInt.get(range, precision);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+ break;
+
+ case GL_FRAGMENT_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ mCaps.fragmentLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ mCaps.fragmentMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ mCaps.fragmentHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ mCaps.fragmentLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ mCaps.fragmentMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ mCaps.fragmentHighpInt.get(range, precision);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
return;
+ }
+}
+
+void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->getSource(bufsize, length, source);
+}
+
+void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getUniformfv(this, location, params);
+}
+
+void Context::getUniformiv(GLuint program, GLint location, GLint *params)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getUniformiv(this, location, params);
+}
+
+GLint Context::getUniformLocation(GLuint program, const GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ return programObject->getUniformLocation(name);
+}
+
+GLboolean Context::isBuffer(GLuint buffer)
+{
+ if (buffer == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
+}
+
+GLboolean Context::isEnabled(GLenum cap)
+{
+ return mGLState.getEnableFeature(cap);
+}
+
+GLboolean Context::isFramebuffer(GLuint framebuffer)
+{
+ if (framebuffer == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
+}
+
+GLboolean Context::isProgram(GLuint program)
+{
+ if (program == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getProgram(program) ? GL_TRUE : GL_FALSE);
+}
+
+GLboolean Context::isRenderbuffer(GLuint renderbuffer)
+{
+ if (renderbuffer == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
+}
+
+GLboolean Context::isShader(GLuint shader)
+{
+ if (shader == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getShader(shader) ? GL_TRUE : GL_FALSE);
+}
+
+GLboolean Context::isTexture(GLuint texture)
+{
+ if (texture == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getTexture(texture) ? GL_TRUE : GL_FALSE);
+}
+
+void Context::linkProgram(GLuint program)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ handleError(programObject->link(this));
+ mGLState.onProgramExecutableChange(programObject);
+}
+
+void Context::releaseShaderCompiler()
+{
+ mCompiler.set(this, nullptr);
+}
+
+void Context::shaderBinary(GLsizei n,
+ const GLuint *shaders,
+ GLenum binaryformat,
+ const void *binary,
+ GLsizei length)
+{
+ // No binary shader formats are supported.
+ UNIMPLEMENTED();
+}
+
+void Context::shaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->setSource(count, string, length);
+}
+
+void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+}
+
+void Context::stencilMask(GLuint mask)
+{
+ stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+}
+
+void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+}
+
+void Context::uniform1f(GLint location, GLfloat x)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform1fv(location, 1, &x);
+}
+
+void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform1fv(location, count, v);
+}
+
+void Context::uniform1i(GLint location, GLint x)
+{
+ Program *program = mGLState.getProgram();
+ if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
+ {
+ mGLState.setObjectDirty(GL_PROGRAM);
+ }
+}
+
+void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ Program *program = mGLState.getProgram();
+ if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
+ {
+ mGLState.setObjectDirty(GL_PROGRAM);
+ }
+}
+
+void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ GLfloat xy[2] = {x, y};
+ Program *program = mGLState.getProgram();
+ program->setUniform2fv(location, 1, xy);
+}
+
+void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform2fv(location, count, v);
+}
+
+void Context::uniform2i(GLint location, GLint x, GLint y)
+{
+ GLint xy[2] = {x, y};
+ Program *program = mGLState.getProgram();
+ program->setUniform2iv(location, 1, xy);
+}
+
+void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform2iv(location, count, v);
+}
+
+void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat xyz[3] = {x, y, z};
+ Program *program = mGLState.getProgram();
+ program->setUniform3fv(location, 1, xyz);
+}
+
+void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform3fv(location, count, v);
+}
+
+void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ GLint xyz[3] = {x, y, z};
+ Program *program = mGLState.getProgram();
+ program->setUniform3iv(location, 1, xyz);
+}
+
+void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform3iv(location, count, v);
+}
+
+void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat xyzw[4] = {x, y, z, w};
+ Program *program = mGLState.getProgram();
+ program->setUniform4fv(location, 1, xyzw);
+}
+
+void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform4fv(location, count, v);
+}
+
+void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ GLint xyzw[4] = {x, y, z, w};
+ Program *program = mGLState.getProgram();
+ program->setUniform4iv(location, 1, xyzw);
+}
+
+void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform4iv(location, count, v);
+}
+
+void Context::uniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix3fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void Context::validateProgram(GLuint program)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->validate(mCaps);
+}
+
+void Context::validateProgramPipeline(GLuint pipeline)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getProgramBinary(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject != nullptr);
+
+ handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
+}
+
+void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject != nullptr);
+
+ handleError(programObject->loadBinary(this, binaryFormat, binary, length));
+}
+
+void Context::uniform1ui(GLint location, GLuint v0)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform1uiv(location, 1, &v0);
+}
+
+void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ Program *program = mGLState.getProgram();
+ const GLuint xy[] = {v0, v1};
+ program->setUniform2uiv(location, 1, xy);
+}
+
+void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Program *program = mGLState.getProgram();
+ const GLuint xyz[] = {v0, v1, v2};
+ program->setUniform3uiv(location, 1, xyz);
+}
+
+void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Program *program = mGLState.getProgram();
+ const GLuint xyzw[] = {v0, v1, v2, v3};
+ program->setUniform4uiv(location, 1, xyzw);
+}
+
+void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform1uiv(location, count, value);
+}
+void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform2uiv(location, count, value);
+}
+
+void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform3uiv(location, count, value);
+}
+
+void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniform4uiv(location, count, value);
+}
+
+void Context::genQueries(GLsizei n, GLuint *ids)
+{
+ for (GLsizei i = 0; i < n; i++)
+ {
+ GLuint handle = mQueryHandleAllocator.allocate();
+ mQueryMap.assign(handle, nullptr);
+ ids[i] = handle;
+ }
+}
+
+void Context::deleteQueries(GLsizei n, const GLuint *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ GLuint query = ids[i];
+
+ Query *queryObject = nullptr;
+ if (mQueryMap.erase(query, &queryObject))
+ {
+ mQueryHandleAllocator.release(query);
+ if (queryObject)
+ {
+ queryObject->release(this);
+ }
+ }
+ }
+}
+
+GLboolean Context::isQuery(GLuint id)
+{
+ return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
+}
+
+void Context::uniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = mGLState.getProgram();
+ program->setUniformMatrix4x3fv(location, count, transpose, value);
+}
+
+void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
+{
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ GLuint vertexArray = arrays[arrayIndex];
+
+ if (arrays[arrayIndex] != 0)
+ {
+ VertexArray *vertexArrayObject = nullptr;
+ if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
+ {
+ if (vertexArrayObject != nullptr)
+ {
+ detachVertexArray(vertexArray);
+ vertexArrayObject->onDestroy(this);
+ }
+
+ mVertexArrayHandleAllocator.release(vertexArray);
+ }
}
}
}
+void Context::genVertexArrays(GLsizei n, GLuint *arrays)
+{
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
+ mVertexArrayMap.assign(vertexArray, nullptr);
+ arrays[arrayIndex] = vertexArray;
+ }
+}
+
+bool Context::isVertexArray(GLuint array)
+{
+ if (array == 0)
+ {
+ return GL_FALSE;
+ }
+
+ VertexArray *vao = getVertexArray(array);
+ return (vao != nullptr ? GL_TRUE : GL_FALSE);
+}
+
+void Context::endTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
+ transformFeedback->end(this);
+}
+
+void Context::transformFeedbackVaryings(GLuint program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+}
+
+void Context::getTransformFeedbackVarying(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+}
+
+void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ GLuint transformFeedback = ids[i];
+ if (transformFeedback == 0)
+ {
+ continue;
+ }
+
+ TransformFeedback *transformFeedbackObject = nullptr;
+ if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
+ {
+ if (transformFeedbackObject != nullptr)
+ {
+ detachTransformFeedback(transformFeedback);
+ transformFeedbackObject->release(this);
+ }
+
+ mTransformFeedbackHandleAllocator.release(transformFeedback);
+ }
+ }
+}
+
+void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
+ mTransformFeedbackMap.assign(transformFeedback, nullptr);
+ ids[i] = transformFeedback;
+ }
+}
+
+bool Context::isTransformFeedback(GLuint id)
+{
+ if (id == 0)
+ {
+ // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
+ // returns FALSE
+ return GL_FALSE;
+ }
+
+ const TransformFeedback *transformFeedback = getTransformFeedback(id);
+ return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
+}
+
+void Context::pauseTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
+ transformFeedback->pause();
+}
+
+void Context::resumeTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
+ transformFeedback->resume();
+}
+
+void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
+{
+ const Program *programObject = getProgram(program);
+ programObject->getUniformuiv(this, location, params);
+}
+
+GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
+{
+ const Program *programObject = getProgram(program);
+ return programObject->getFragDataLocation(name);
+}
+
+void Context::getUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices)
+{
+ const Program *programObject = getProgram(program);
+ if (!programObject->isLinked())
+ {
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ uniformIndices[uniformId] = GL_INVALID_INDEX;
+ }
+ }
+ else
+ {
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
+ }
+ }
+}
+
+void Context::getActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params)
+{
+ const Program *programObject = getProgram(program);
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ const GLuint index = uniformIndices[uniformId];
+ params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
+ }
+}
+
+GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
+{
+ const Program *programObject = getProgram(program);
+ return programObject->getUniformBlockIndex(uniformBlockName);
+}
+
+void Context::getActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ const Program *programObject = getProgram(program);
+ QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
+}
+
+void Context::getActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName)
+{
+ const Program *programObject = getProgram(program);
+ programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
+}
+
+void Context::uniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ Program *programObject = getProgram(program);
+ programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
+}
+
+GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
+{
+ GLuint handle = mState.mSyncs->createSync(mImplementation.get());
+ GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
+
+ Sync *syncObject = getSync(syncHandle);
+ Error error = syncObject->set(condition, flags);
+ if (error.isError())
+ {
+ deleteSync(syncHandle);
+ handleError(error);
+ return nullptr;
+ }
+
+ return syncHandle;
+}
+
+GLboolean Context::isSync(GLsync sync)
+{
+ return (getSync(sync) != nullptr);
+}
+
+GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Sync *syncObject = getSync(sync);
+
+ GLenum result = GL_WAIT_FAILED;
+ handleError(syncObject->clientWait(flags, timeout, &result));
+ return result;
+}
+
+void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Sync *syncObject = getSync(sync);
+ handleError(syncObject->serverWait(flags, timeout));
+}
+
+void Context::getInteger64v(GLenum pname, GLint64 *params)
+{
+ GLenum nativeType = GL_NONE;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ getInteger64vImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
+{
+ Buffer *buffer = mGLState.getTargetBuffer(target);
+ QueryBufferParameteri64v(buffer, pname, params);
+}
+
+void Context::genSamplers(GLsizei count, GLuint *samplers)
+{
+ for (int i = 0; i < count; i++)
+ {
+ samplers[i] = mState.mSamplers->createSampler();
+ }
+}
+
+void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
+{
+ for (int i = 0; i < count; i++)
+ {
+ GLuint sampler = samplers[i];
+
+ if (mState.mSamplers->getSampler(sampler))
+ {
+ detachSampler(sampler);
+ }
+
+ mState.mSamplers->deleteObject(this, sampler);
+ }
+}
+
+void Context::getInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLint *params)
+{
+ const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
+ QueryInternalFormativ(formatCaps, pname, bufSize, params);
+}
+
+void Context::programUniform1i(GLuint program, GLint location, GLint v0)
+{
+ programUniform1iv(program, location, 1, &v0);
+}
+
+void Context::programUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ GLint xy[2] = {v0, v1};
+ programUniform2iv(program, location, 1, xy);
+}
+
+void Context::programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ GLint xyz[3] = {v0, v1, v2};
+ programUniform3iv(program, location, 1, xyz);
+}
+
+void Context::programUniform4i(GLuint program,
+ GLint location,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3)
+{
+ GLint xyzw[4] = {v0, v1, v2, v3};
+ programUniform4iv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ programUniform1uiv(program, location, 1, &v0);
+}
+
+void Context::programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ GLuint xy[2] = {v0, v1};
+ programUniform2uiv(program, location, 1, xy);
+}
+
+void Context::programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ GLuint xyz[3] = {v0, v1, v2};
+ programUniform3uiv(program, location, 1, xyz);
+}
+
+void Context::programUniform4ui(GLuint program,
+ GLint location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ GLuint xyzw[4] = {v0, v1, v2, v3};
+ programUniform4uiv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ programUniform1fv(program, location, 1, &v0);
+}
+
+void Context::programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ GLfloat xy[2] = {v0, v1};
+ programUniform2fv(program, location, 1, xy);
+}
+
+void Context::programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ GLfloat xyz[3] = {v0, v1, v2};
+ programUniform3fv(program, location, 1, xyz);
+}
+
+void Context::programUniform4f(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ GLfloat xyzw[4] = {v0, v1, v2, v3};
+ programUniform4fv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ if (programObject->setUniform1iv(location, count, value) ==
+ Program::SetUniformResult::SamplerChanged)
+ {
+ mGLState.setObjectDirty(GL_PROGRAM);
+ }
+}
+
+void Context::programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform2iv(location, count, value);
+}
+
+void Context::programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform3iv(location, count, value);
+}
+
+void Context::programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform4iv(location, count, value);
+}
+
+void Context::programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform1uiv(location, count, value);
+}
+
+void Context::programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform2uiv(location, count, value);
+}
+
+void Context::programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform3uiv(location, count, value);
+}
+
+void Context::programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform4uiv(location, count, value);
+}
+
+void Context::programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform1fv(location, count, value);
+}
+
+void Context::programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform2fv(location, count, value);
+}
+
+void Context::programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform3fv(location, count, value);
+}
+
+void Context::programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniform4fv(location, count, value);
+}
+
+void Context::programUniformMatrix2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgram(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4x3fv(location, count, transpose, value);
+}
+
+void Context::onTextureChange(const Texture *texture)
+{
+ // Conservatively assume all textures are dirty.
+ // TODO(jmadill): More fine-grained update.
+ mGLState.setObjectDirty(GL_TEXTURE);
+}
+
+void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
+{
+ for (int i = 0; i < count; i++)
+ {
+ pipelines[i] = createProgramPipeline();
+ }
+}
+
+void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines)
+{
+ for (int i = 0; i < count; i++)
+ {
+ if (pipelines[i] != 0)
+ {
+ deleteProgramPipeline(pipelines[i]);
+ }
+ }
+}
+
+GLboolean Context::isProgramPipeline(GLuint pipeline)
+{
+ if (pipeline == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
+}
+
} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Context.h b/src/3rdparty/angle/src/libANGLE/Context.h
index 6b82eb7cb9..38c4e7b4d1 100644
--- a/src/3rdparty/angle/src/libANGLE/Context.h
+++ b/src/3rdparty/angle/src/libANGLE/Context.h
@@ -10,25 +10,28 @@
#ifndef LIBANGLE_CONTEXT_H_
#define LIBANGLE_CONTEXT_H_
+#include <set>
+#include <string>
+
+#include "angle_gl.h"
+#include "common/MemoryBuffer.h"
#include "common/angleutils.h"
-#include "libANGLE/RefCountObject.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Constants.h"
-#include "libANGLE/Data.h"
+#include "libANGLE/ContextState.h"
#include "libANGLE/Error.h"
#include "libANGLE/HandleAllocator.h"
+#include "libANGLE/PackedGLEnums.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/ResourceMap.h"
#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/Workarounds.h"
#include "libANGLE/angletypes.h"
-#include "angle_gl.h"
-
-#include <string>
-#include <set>
-#include <map>
-
namespace rx
{
-class Renderer;
+class ContextImpl;
+class EGLImplFactory;
}
namespace egl
@@ -36,41 +39,44 @@ namespace egl
class AttributeMap;
class Surface;
struct Config;
+class Thread;
}
namespace gl
{
+class Buffer;
class Compiler;
-class Shader;
-class Program;
-class Texture;
-class Framebuffer;
-class Renderbuffer;
class FenceNV;
-class FenceSync;
+class Sync;
+class Framebuffer;
+class MemoryProgramCache;
+class Program;
class Query;
-class ResourceManager;
-class Buffer;
-struct VertexAttribute;
-class VertexArray;
+class Renderbuffer;
class Sampler;
+class Shader;
+class Texture;
class TransformFeedback;
+class VertexArray;
+struct VertexAttribute;
+class ProgramPipeline;
class Context final : public ValidationContext
{
public:
- Context(const egl::Config *config,
+ Context(rx::EGLImplFactory *implFactory,
+ const egl::Config *config,
const Context *shareContext,
- rx::Renderer *renderer,
- const egl::AttributeMap &attribs);
-
- virtual ~Context();
+ TextureManager *shareTextures,
+ MemoryProgramCache *memoryProgramCache,
+ const egl::AttributeMap &attribs,
+ const egl::DisplayExtensions &displayExtensions);
- void makeCurrent(egl::Surface *surface);
- void releaseSurface();
+ egl::Error onDestroy(const egl::Display *display);
+ ~Context() override;
- virtual void markContextLost();
- bool isContextLost();
+ egl::Error makeCurrent(egl::Display *display, egl::Surface *surface);
+ egl::Error releaseSurface(const egl::Display *display);
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
@@ -79,18 +85,30 @@ class Context final : public ValidationContext
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
- GLuint createSampler();
- GLuint createTransformFeedback();
- GLsync createFenceSync();
+ GLuint createPaths(GLsizei range);
+ GLuint createProgramPipeline();
+ GLuint createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings);
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
- void deleteSampler(GLuint sampler);
- void deleteTransformFeedback(GLuint transformFeedback);
- void deleteFenceSync(GLsync fenceSync);
+ void deletePaths(GLuint first, GLsizei range);
+ void deleteProgramPipeline(GLuint pipeline);
+
+ // CHROMIUM_path_rendering
+ bool hasPathData(GLuint path) const;
+ bool hasPath(GLuint path) const;
+ void setPathCommands(GLuint path,
+ GLsizei numCommands,
+ const GLubyte *commands,
+ GLsizei numCoords,
+ GLenum coordType,
+ const void *coords);
+ void setPathParameterf(GLuint path, GLenum pname, GLfloat value);
+ void getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const;
+ void setPathStencilFunc(GLenum func, GLint ref, GLuint mask);
// Framebuffers are owned by the Context, so these methods do not pass through
GLuint createFramebuffer();
@@ -100,54 +118,90 @@ class Context final : public ValidationContext
GLuint createFenceNV();
void deleteFenceNV(GLuint fence);
- // Queries are owned by the Context;
- GLuint createQuery();
- void deleteQuery(GLuint query);
-
- // Vertex arrays are owned by the Context
- GLuint createVertexArray();
- void deleteVertexArray(GLuint vertexArray);
-
- void bindArrayBuffer(GLuint buffer);
- void bindElementArrayBuffer(GLuint buffer);
void bindTexture(GLenum target, GLuint handle);
void bindReadFramebuffer(GLuint framebufferHandle);
void bindDrawFramebuffer(GLuint framebufferHandle);
- void bindRenderbuffer(GLuint renderbuffer);
- void bindVertexArray(GLuint vertexArray);
- void bindSampler(GLuint textureUnit, GLuint sampler);
- void bindGenericUniformBuffer(GLuint buffer);
- void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
- void bindGenericTransformFeedbackBuffer(GLuint buffer);
- void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
- void bindCopyReadBuffer(GLuint buffer);
- void bindCopyWriteBuffer(GLuint buffer);
- void bindPixelPackBuffer(GLuint buffer);
- void bindPixelUnpackBuffer(GLuint buffer);
+ void bindVertexArray(GLuint vertexArrayHandle);
+ void bindVertexBuffer(GLuint bindingIndex,
+ GLuint bufferHandle,
+ GLintptr offset,
+ GLsizei stride);
+ void bindSampler(GLuint textureUnit, GLuint samplerHandle);
+ void bindImageTexture(GLuint unit,
+ GLuint texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format);
void useProgram(GLuint program);
- void bindTransformFeedback(GLuint transformFeedback);
+ void useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
+ void bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle);
+ void bindProgramPipeline(GLuint pipelineHandle);
- Error beginQuery(GLenum target, GLuint query);
- Error endQuery(GLenum target);
- Error queryCounter(GLuint id, GLenum target);
+ void beginQuery(GLenum target, GLuint query);
+ void endQuery(GLenum target);
+ void queryCounter(GLuint id, GLenum target);
void getQueryiv(GLenum target, GLenum pname, GLint *params);
- Error getQueryObjectiv(GLuint id, GLenum pname, GLint *params);
- Error getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
- Error getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params);
- Error getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params);
-
- void setVertexAttribDivisor(GLuint index, GLuint divisor);
+ void getQueryObjectiv(GLuint id, GLenum pname, GLint *params);
+ void getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
+ void getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params);
+ void getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params);
+
+ void vertexAttribDivisor(GLuint index, GLuint divisor);
+ void vertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
+
+ void getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params);
+ void getFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+ void getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params);
+
+ void getTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
+ void getTexParameteriv(GLenum target, GLenum pname, GLint *params);
+ void getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
+ void getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameterfv(GLenum target, GLenum pname, const GLfloat *params);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+ void texParameteriv(GLenum target, GLenum pname, const GLint *params);
void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
+ void samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
- GLint getSamplerParameteri(GLuint sampler, GLenum pname);
- GLfloat getSamplerParameterf(GLuint sampler, GLenum pname);
+ void samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param);
+
+ void getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
+ void getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params);
+
+ void programParameteri(GLuint program, GLenum pname, GLint value);
+
+ GLuint getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name);
+ void getProgramResourceName(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+ GLint getProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name);
+ void getProgramResourceiv(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+
+ void getProgramInterfaceiv(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params);
Buffer *getBuffer(GLuint handle) const;
FenceNV *getFenceNV(GLuint handle);
- FenceSync *getFenceSync(GLsync handle) const;
- Shader *getShader(GLuint handle) const;
- Program *getProgram(GLuint handle) const;
+ Sync *getSync(GLsync handle) const;
Texture *getTexture(GLuint handle) const;
Framebuffer *getFramebuffer(GLuint handle) const;
Renderbuffer *getRenderbuffer(GLuint handle) const;
@@ -156,8 +210,16 @@ class Context final : public ValidationContext
Query *getQuery(GLuint handle, bool create, GLenum type);
Query *getQuery(GLuint handle) const;
TransformFeedback *getTransformFeedback(GLuint handle) const;
- LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
- LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
+ ProgramPipeline *getProgramPipeline(GLuint handle) const;
+
+ void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+ void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label);
+ void getObjectLabel(GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label) const;
+ void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) const;
Texture *getTargetTexture(GLenum target) const;
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
@@ -170,16 +232,108 @@ class Context final : public ValidationContext
bool isTransformFeedbackGenerated(GLuint vertexArray);
void getBooleanv(GLenum pname, GLboolean *params);
+ void getBooleanvImpl(GLenum pname, GLboolean *params);
void getFloatv(GLenum pname, GLfloat *params);
+ void getFloatvImpl(GLenum pname, GLfloat *params);
void getIntegerv(GLenum pname, GLint *params);
- void getInteger64v(GLenum pname, GLint64 *params);
+ void getIntegervImpl(GLenum pname, GLint *params);
+ void getInteger64vImpl(GLenum pname, GLint64 *params);
void getPointerv(GLenum pname, void **params) const;
-
- bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
- bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
-
- bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
- bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
+ void getBooleani_v(GLenum target, GLuint index, GLboolean *data);
+ void getIntegeri_v(GLenum target, GLuint index, GLint *data);
+ void getInteger64i_v(GLenum target, GLuint index, GLint64 *data);
+
+ void activeShaderProgram(GLuint pipeline, GLuint program);
+ void activeTexture(GLenum texture);
+ void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void clearDepthf(GLfloat depth);
+ void clearStencil(GLint s);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void cullFace(CullFaceMode mode);
+ void depthFunc(GLenum func);
+ void depthMask(GLboolean flag);
+ void depthRangef(GLfloat zNear, GLfloat zFar);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void frontFace(GLenum mode);
+ void hint(GLenum target, GLenum mode);
+ void lineWidth(GLfloat width);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+ void sampleCoverage(GLfloat value, GLboolean invert);
+ void sampleMaski(GLuint maskNumber, GLbitfield mask);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void vertexAttrib1f(GLuint index, GLfloat x);
+ void vertexAttrib1fv(GLuint index, const GLfloat *values);
+ void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+ void vertexAttrib2fv(GLuint index, const GLfloat *values);
+ void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ void vertexAttrib3fv(GLuint index, const GLfloat *values);
+ void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void vertexAttrib4fv(GLuint index, const GLfloat *values);
+ void vertexAttribFormat(GLuint attribIndex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeOffset);
+ void vertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, GLuint relativeOffset);
+ void vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex);
+ void vertexAttribPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr);
+ void vertexAttribIPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+ void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void vertexAttribI4iv(GLuint index, const GLint *v);
+ void vertexAttribI4uiv(GLuint index, const GLuint *v);
+ void getVertexAttribiv(GLuint index, GLenum pname, GLint *params);
+ void getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
+ void getVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
+ void getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
+ void getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer);
+
+ void debugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+ void debugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+ void debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam);
+ GLuint getDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog);
+ void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message);
+ void popDebugGroup();
void clear(GLbitfield mask);
void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
@@ -187,27 +341,23 @@ class Context final : public ValidationContext
void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
- Error drawArrays(GLenum mode, GLint first, GLsizei count);
- Error drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
-
- Error drawElements(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- const IndexRange &indexRange);
- Error drawElementsInstanced(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- GLsizei instances,
- const IndexRange &indexRange);
- Error drawRangeElements(GLenum mode,
- GLuint start,
- GLuint end,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- const IndexRange &indexRange);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+
+ void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+ void drawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instances);
+ void drawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices);
+ void drawArraysIndirect(GLenum mode, const void *indirect);
+ void drawElementsIndirect(GLenum mode, GLenum type, const void *indirect);
void blitFramebuffer(GLint srcX0,
GLint srcY0,
@@ -226,7 +376,7 @@ class Context final : public ValidationContext
GLsizei height,
GLenum format,
GLenum type,
- GLvoid *pixels);
+ void *pixels);
void copyTexImage2D(GLenum target,
GLint level,
@@ -272,6 +422,18 @@ class Context final : public ValidationContext
GLuint texture,
GLint level,
GLint layer);
+ void framebufferTextureMultiviewLayeredANGLE(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+ void framebufferTextureMultiviewSideBySideANGLE(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLsizei numViews,
+ const GLint *viewportOffsets);
void drawBuffers(GLsizei n, const GLenum *bufs);
void readBuffer(GLenum mode);
@@ -286,40 +448,596 @@ class Context final : public ValidationContext
GLsizei width,
GLsizei height);
- Error flush();
- Error finish();
+ void texImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ void texImage3D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ void texSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ void texSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ void compressedTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+ void compressedTexImage3D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+ void compressedTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+ void compressedTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+ void copyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+ void copySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+ void compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
+
+ void generateMipmap(GLenum target);
+
+ void flush();
+ void finish();
+
+ void getBufferPointerv(BufferBinding target, GLenum pname, void **params);
+ void *mapBuffer(BufferBinding target, GLenum access);
+ GLboolean unmapBuffer(BufferBinding target);
+ void *mapBufferRange(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+ void flushMappedBufferRange(BufferBinding target, GLintptr offset, GLsizeiptr length);
+
+ void beginTransformFeedback(GLenum primitiveMode);
+
+ bool hasActiveTransformFeedback(GLuint program) const;
void insertEventMarker(GLsizei length, const char *marker);
void pushGroupMarker(GLsizei length, const char *marker);
void popGroupMarker();
- void recordError(const Error &error) override;
+ void bindUniformLocation(GLuint program, GLint location, const GLchar *name);
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void renderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+ void getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+
+ // CHROMIUM_framebuffer_mixed_samples
+ void setCoverageModulation(GLenum components);
+
+ // CHROMIUM_path_rendering
+ void loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix);
+ void loadPathRenderingIdentityMatrix(GLenum matrixMode);
+ void stencilFillPath(GLuint path, GLenum fillMode, GLuint mask);
+ void stencilStrokePath(GLuint path, GLint reference, GLuint mask);
+ void coverFillPath(GLuint path, GLenum coverMode);
+ void coverStrokePath(GLuint path, GLenum coverMode);
+ void stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+ void stencilThenCoverStrokePath(GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+ void coverFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void coverStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBAse,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilThenCoverFillPathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilThenCoverStrokePathInstanced(GLsizei numPaths,
+ GLenum pathNameType,
+ const void *paths,
+ GLuint pathBase,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name);
+ void programPathFragmentInputGen(GLuint program,
+ GLint location,
+ GLenum genMode,
+ GLint components,
+ const GLfloat *coeffs);
+
+ void bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage);
+ void bufferSubData(BufferBinding target, GLintptr offset, GLsizeiptr size, const void *data);
+ void attachShader(GLuint program, GLuint shader);
+ void bindAttribLocation(GLuint program, GLuint index, const GLchar *name);
+ void bindBuffer(BufferBinding target, GLuint buffer);
+ void bindBufferBase(BufferBinding target, GLuint index, GLuint buffer);
+ void bindBufferRange(BufferBinding target,
+ GLuint index,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size);
+ void bindFramebuffer(GLenum target, GLuint framebuffer);
+ void bindRenderbuffer(GLenum target, GLuint renderbuffer);
+
+ void texStorage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+
+ void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
+
+ void copyBufferSubData(BufferBinding readTarget,
+ BufferBinding writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void compileShader(GLuint shader);
+ void deleteBuffers(GLsizei n, const GLuint *buffers);
+ void deleteFramebuffers(GLsizei n, const GLuint *framebuffers);
+ void deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
+ void deleteTextures(GLsizei n, const GLuint *textures);
+ void detachShader(GLuint program, GLuint shader);
+ void genBuffers(GLsizei n, GLuint *buffers);
+ void genFramebuffers(GLsizei n, GLuint *framebuffers);
+ void genRenderbuffers(GLsizei n, GLuint *renderbuffers);
+ void genTextures(GLsizei n, GLuint *textures);
+ void getActiveAttrib(GLuint program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+ void getActiveUniform(GLuint program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+ void getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders);
+ GLint getAttribLocation(GLuint program, const GLchar *name);
+ void getProgramiv(GLuint program, GLenum pname, GLint *params);
+ void getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
+ void getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog);
+ void getProgramPipelineInfoLog(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+ void getShaderiv(GLuint shader, GLenum pname, GLint *params);
+ void getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog);
+ void getShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision);
+ void getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+ void getUniformfv(GLuint program, GLint location, GLfloat *params);
+ void getUniformiv(GLuint program, GLint location, GLint *params);
+ GLint getUniformLocation(GLuint program, const GLchar *name);
+ GLboolean isBuffer(GLuint buffer);
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(GLuint framebuffer);
+ GLboolean isProgram(GLuint program);
+ GLboolean isRenderbuffer(GLuint renderbuffer);
+ GLboolean isShader(GLuint shader);
+ GLboolean isTexture(GLuint texture);
+ void linkProgram(GLuint program);
+ void releaseShaderCompiler();
+ void shaderBinary(GLsizei n,
+ const GLuint *shaders,
+ GLenum binaryformat,
+ const void *binary,
+ GLsizei length);
+ void shaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint mask);
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ void uniform1f(GLint location, GLfloat x);
+ void uniform1fv(GLint location, GLsizei count, const GLfloat *v);
+ void uniform1i(GLint location, GLint x);
+ void uniform1iv(GLint location, GLsizei count, const GLint *v);
+ void uniform2f(GLint location, GLfloat x, GLfloat y);
+ void uniform2fv(GLint location, GLsizei count, const GLfloat *v);
+ void uniform2i(GLint location, GLint x, GLint y);
+ void uniform2iv(GLint location, GLsizei count, const GLint *v);
+ void uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void uniform3fv(GLint location, GLsizei count, const GLfloat *v);
+ void uniform3i(GLint location, GLint x, GLint y, GLint z);
+ void uniform3iv(GLint location, GLsizei count, const GLint *v);
+ void uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void uniform4fv(GLint location, GLsizei count, const GLfloat *v);
+ void uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void uniform4iv(GLint location, GLsizei count, const GLint *v);
+ void uniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void validateProgram(GLuint program);
+ void validateProgramPipeline(GLuint pipeline);
+
+ void genQueries(GLsizei n, GLuint *ids);
+ void deleteQueries(GLsizei n, const GLuint *ids);
+ GLboolean isQuery(GLuint id);
+
+ void uniform1ui(GLint location, GLuint v0);
+ void uniform2ui(GLint location, GLuint v0, GLuint v1);
+ void uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+ void uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+ void uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+ void uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+
+ void uniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void uniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void uniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void uniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void uniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void uniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void deleteVertexArrays(GLsizei n, const GLuint *arrays);
+ void genVertexArrays(GLsizei n, GLuint *arrays);
+ bool isVertexArray(GLuint array);
+
+ void endTransformFeedback();
+ void transformFeedbackVaryings(GLuint program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode);
+ void getTransformFeedbackVarying(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name);
+
+ void deleteTransformFeedbacks(GLsizei n, const GLuint *ids);
+ void genTransformFeedbacks(GLsizei n, GLuint *ids);
+ bool isTransformFeedback(GLuint id);
+ void pauseTransformFeedback();
+ void resumeTransformFeedback();
+
+ void getProgramBinary(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary);
+ void programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+
+ void getUniformuiv(GLuint program, GLint location, GLuint *params);
+ GLint getFragDataLocation(GLuint program, const GLchar *name);
+ void getUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices);
+ void getActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params);
+ GLuint getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName);
+ void getActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+ void getActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName);
+ void uniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+ GLsync fenceSync(GLenum condition, GLbitfield flags);
+ GLboolean isSync(GLsync sync);
+ void deleteSync(GLsync sync);
+ GLenum clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void getInteger64v(GLenum pname, GLint64 *params);
+
+ void getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params);
+ void genSamplers(GLsizei count, GLuint *samplers);
+ void deleteSamplers(GLsizei count, const GLuint *samplers);
+ void getInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLint *params);
+
+ void programUniform1i(GLuint program, GLint location, GLint v0);
+ void programUniform2i(GLuint program, GLint location, GLint v0, GLint v1);
+ void programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ void programUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ void programUniform1ui(GLuint program, GLint location, GLuint v0);
+ void programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1);
+ void programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void programUniform4ui(GLuint program,
+ GLint location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+ void programUniform1f(GLuint program, GLint location, GLfloat v0);
+ void programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+ void programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ void programUniform4f(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+ void programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+
+ void programUniformMatrix2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix2x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix3x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix2x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix4x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix3x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void programUniformMatrix4x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void deleteProgramPipelines(GLsizei n, const GLuint *pipelines);
+ void genProgramPipelines(GLsizei n, GLuint *pipelines);
+ GLboolean isProgramPipeline(GLuint pipeline);
+
+ // Consumes the error.
+ void handleError(const Error &error) override;
GLenum getError();
+ void markContextLost();
+ bool isContextLost();
GLenum getResetStatus();
- virtual bool isResetNotificationEnabled();
+ bool isResetNotificationEnabled();
const egl::Config *getConfig() const;
EGLenum getClientType() const;
EGLenum getRenderBuffer() const;
- const std::string &getRendererString() const;
+ const GLubyte *getString(GLenum name) const;
+ const GLubyte *getStringi(GLenum name, GLuint index) const;
- const std::string &getExtensionString() const;
- const std::string &getExtensionString(size_t idx) const;
size_t getExtensionStringCount() const;
- rx::Renderer *getRenderer() { return mRenderer; }
+ bool isExtensionRequestable(const char *name);
+ void requestExtension(const char *name);
+ size_t getRequestableExtensionStringCount() const;
- State &getState() { return mState; }
+ rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
+ const Workarounds &getWorkarounds() const;
- void syncRendererState();
- void syncRendererState(const State::DirtyBits &bitMask);
+ void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+ void framebufferParameteri(GLenum target, GLenum pname, GLint param);
+
+ Error getScratchBuffer(size_t requestedSizeBytes, angle::MemoryBuffer **scratchBufferOut) const;
+ Error getZeroFilledBuffer(size_t requstedSizeBytes, angle::MemoryBuffer **zeroBufferOut) const;
+
+ void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
+ void dispatchComputeIndirect(GLintptr indirect);
+
+ MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
+
+ template <EntryPoint EP, typename... ParamsT>
+ void gatherParams(ParamsT &&... params);
+
+ void texStorage2D(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height);
+ void texStorage3D(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+ void memoryBarrier(GLbitfield barriers);
+ void memoryBarrierByRegion(GLbitfield barriers);
+
+ // Notification for a state change in a Texture.
+ void onTextureChange(const Texture *texture);
+
+ egl::Display *getCurrentDisplay() const { return mCurrentDisplay; }
+ egl::Surface *getCurrentDrawSurface() const { return mCurrentSurface; }
+ egl::Surface *getCurrentReadSurface() const { return mCurrentSurface; }
+
+ bool isRobustResourceInitEnabled() const { return mGLState.isRobustResourceInitEnabled(); }
private:
- void checkVertexArrayAllocation(GLuint vertexArray);
- void checkTransformFeedbackAllocation(GLuint transformFeedback);
- Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle);
+ Error prepareForDraw();
+ void syncRendererState();
+ void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
+ void syncStateForReadPixels();
+ void syncStateForTexImage();
+ void syncStateForClear();
+ void syncStateForBlit();
+ VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
+ TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
@@ -328,11 +1046,20 @@ class Context final : public ValidationContext
void detachVertexArray(GLuint vertexArray);
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
+ void detachProgramPipeline(GLuint pipeline);
void initRendererString();
+ void initVersionStrings();
void initExtensionStrings();
- void initCaps(GLuint clientVersion);
+ void initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit);
+ void updateCaps();
+ void initWorkarounds();
+
+ LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
+ LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
+
+ std::unique_ptr<rx::ContextImpl> mImplementation;
// Caps to use for validation
Caps mCaps;
@@ -340,42 +1067,35 @@ class Context final : public ValidationContext
Extensions mExtensions;
Limitations mLimitations;
- // Shader compiler
- Compiler *mCompiler;
-
- rx::Renderer *const mRenderer;
- State mState;
+ // Shader compiler. Lazily initialized hence the mutable value.
+ mutable BindingPointer<Compiler> mCompiler;
- int mClientVersion;
+ State mGLState;
const egl::Config *mConfig;
EGLenum mClientType;
TextureMap mZeroTextures;
- typedef std::map<GLuint, Framebuffer*> FramebufferMap;
- FramebufferMap mFramebufferMap;
- HandleAllocator mFramebufferHandleAllocator;
-
- typedef std::map<GLuint, FenceNV*> FenceNVMap;
- FenceNVMap mFenceNVMap;
+ ResourceMap<FenceNV> mFenceNVMap;
HandleAllocator mFenceNVHandleAllocator;
- typedef std::map<GLuint, Query*> QueryMap;
- QueryMap mQueryMap;
+ ResourceMap<Query> mQueryMap;
HandleAllocator mQueryHandleAllocator;
- typedef std::map<GLuint, VertexArray*> VertexArrayMap;
- VertexArrayMap mVertexArrayMap;
+ ResourceMap<VertexArray> mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator;
- typedef std::map<GLuint, TransformFeedback*> TransformFeedbackMap;
- TransformFeedbackMap mTransformFeedbackMap;
- HandleAllocator mTransformFeedbackAllocator;
+ ResourceMap<TransformFeedback> mTransformFeedbackMap;
+ HandleAllocator mTransformFeedbackHandleAllocator;
- std::string mRendererString;
- std::string mExtensionString;
- std::vector<std::string> mExtensionStrings;
+ const char *mVersionString;
+ const char *mShadingLanguageString;
+ const char *mRendererString;
+ const char *mExtensionString;
+ std::vector<const char *> mExtensionStrings;
+ const char *mRequestableExtensionString;
+ std::vector<const char *> mRequestableExtensionStrings;
// Recorded errors
typedef std::set<GLenum> ErrorSet;
@@ -385,13 +1105,50 @@ class Context final : public ValidationContext
bool mHasBeenCurrent;
bool mContextLost;
GLenum mResetStatus;
+ bool mContextLostForced;
GLenum mResetStrategy;
bool mRobustAccess;
egl::Surface *mCurrentSurface;
-
- ResourceManager *mResourceManager;
+ egl::Display *mCurrentDisplay;
+ Framebuffer *mSurfacelessFramebuffer;
+ bool mWebGLContext;
+ MemoryProgramCache *mMemoryProgramCache;
+
+ State::DirtyBits mTexImageDirtyBits;
+ State::DirtyObjects mTexImageDirtyObjects;
+ State::DirtyBits mReadPixelsDirtyBits;
+ State::DirtyObjects mReadPixelsDirtyObjects;
+ State::DirtyBits mClearDirtyBits;
+ State::DirtyObjects mClearDirtyObjects;
+ State::DirtyBits mBlitDirtyBits;
+ State::DirtyObjects mBlitDirtyObjects;
+
+ Workarounds mWorkarounds;
+
+ // Not really a property of context state. The size and contexts change per-api-call.
+ mutable angle::ScratchBuffer mScratchBuffer;
+ mutable angle::ScratchBuffer mZeroFilledBuffer;
};
+template <EntryPoint EP, typename... ArgsT>
+ANGLE_INLINE void Context::gatherParams(ArgsT &&... args)
+{
+ static_assert(sizeof(EntryPointParamType<EP>) <= kParamsBufferSize,
+ "Params struct too large, please increase kParamsBufferSize.");
+
+ mSavedArgsType = &EntryPointParamType<EP>::TypeInfo;
+
+ // Skip doing any work for ParamsBase/Invalid type.
+ if (!EntryPointParamType<EP>::TypeInfo.isValid())
+ {
+ return;
+ }
+
+ EntryPointParamType<EP> *objBuffer =
+ reinterpret_cast<EntryPointParamType<EP> *>(mParamsBuffer.data());
+ EntryPointParamType<EP>::template Factory<EP>(objBuffer, this, std::forward<ArgsT>(args)...);
+}
+
} // namespace gl
-#endif // LIBANGLE_CONTEXT_H_
+#endif // LIBANGLE_CONTEXT_H_
diff --git a/src/3rdparty/angle/src/libANGLE/ContextState.cpp b/src/3rdparty/angle/src/libANGLE/ContextState.cpp
new file mode 100644
index 0000000000..d109cca76d
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/ContextState.cpp
@@ -0,0 +1,839 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Data.cpp: Container class for all GL relevant state, caps and objects
+
+#include "libANGLE/ContextState.h"
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/ResourceManager.h"
+
+namespace gl
+{
+
+namespace
+{
+
+template <typename T>
+using ContextStateMember = T *(ContextState::*);
+
+template <typename T>
+T *AllocateOrGetSharedResourceManager(const ContextState *shareContextState,
+ ContextStateMember<T> member)
+{
+ if (shareContextState)
+ {
+ T *resourceManager = (*shareContextState).*member;
+ resourceManager->addRef();
+ return resourceManager;
+ }
+ else
+ {
+ return new T();
+ }
+}
+
+TextureManager *AllocateOrGetSharedTextureManager(const ContextState *shareContextState,
+ TextureManager *shareTextures,
+ ContextStateMember<TextureManager> member)
+{
+ if (shareContextState)
+ {
+ TextureManager *textureManager = (*shareContextState).*member;
+ ASSERT(shareTextures == nullptr || textureManager == shareTextures);
+ textureManager->addRef();
+ return textureManager;
+ }
+ else if (shareTextures)
+ {
+ TextureManager *textureManager = shareTextures;
+ textureManager->addRef();
+ return textureManager;
+ }
+ else
+ {
+ return new TextureManager();
+ }
+}
+
+} // anonymous namespace
+
+ContextState::ContextState(ContextID contextIn,
+ const ContextState *shareContextState,
+ TextureManager *shareTextures,
+ const Version &clientVersion,
+ State *stateIn,
+ const Caps &capsIn,
+ const TextureCapsMap &textureCapsIn,
+ const Extensions &extensionsIn,
+ const Limitations &limitationsIn)
+ : mClientVersion(clientVersion),
+ mContext(contextIn),
+ mState(stateIn),
+ mCaps(capsIn),
+ mTextureCaps(textureCapsIn),
+ mExtensions(extensionsIn),
+ mLimitations(limitationsIn),
+ mBuffers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mBuffers)),
+ mShaderPrograms(
+ AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mShaderPrograms)),
+ mTextures(AllocateOrGetSharedTextureManager(shareContextState,
+ shareTextures,
+ &ContextState::mTextures)),
+ mRenderbuffers(
+ AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mRenderbuffers)),
+ mSamplers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSamplers)),
+ mSyncs(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSyncs)),
+ mPaths(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mPaths)),
+ mFramebuffers(new FramebufferManager()),
+ mPipelines(new ProgramPipelineManager())
+{
+}
+
+ContextState::~ContextState()
+{
+ // Handles are released by the Context.
+}
+
+bool ContextState::isWebGL() const
+{
+ return mExtensions.webglCompatibility;
+}
+
+bool ContextState::isWebGL1() const
+{
+ return (isWebGL() && mClientVersion.major == 2);
+}
+
+const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
+{
+ return mTextureCaps.get(internalFormat);
+}
+
+ValidationContext::ValidationContext(const ValidationContext *shareContext,
+ TextureManager *shareTextures,
+ const Version &clientVersion,
+ State *state,
+ const Caps &caps,
+ const TextureCapsMap &textureCaps,
+ const Extensions &extensions,
+ const Limitations &limitations,
+ bool skipValidation)
+ : mState(reinterpret_cast<ContextID>(this),
+ shareContext ? &shareContext->mState : nullptr,
+ shareTextures,
+ clientVersion,
+ state,
+ caps,
+ textureCaps,
+ extensions,
+ limitations),
+ mSkipValidation(skipValidation),
+ mDisplayTextureShareGroup(shareTextures != nullptr)
+{
+}
+
+ValidationContext::~ValidationContext()
+{
+}
+
+bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
+{
+ // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+ // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+ // to the fact that it is stored internally as a float, and so would require conversion
+ // if returned from Context::getIntegerv. Since this conversion is already implemented
+ // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+ // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+ // application.
+ switch (pname)
+ {
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ {
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(getCaps().compressedTextureFormats.size());
+ return true;
+ }
+ case GL_SHADER_BINARY_FORMATS:
+ {
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(getCaps().shaderBinaryFormats.size());
+ return true;
+ }
+
+ case GL_MAX_VERTEX_ATTRIBS:
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ case GL_MAX_VARYING_VECTORS:
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ case GL_MAX_RENDERBUFFER_SIZE:
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ case GL_ARRAY_BUFFER_BINDING:
+ case GL_FRAMEBUFFER_BINDING:
+ case GL_RENDERBUFFER_BINDING:
+ case GL_CURRENT_PROGRAM:
+ case GL_PACK_ALIGNMENT:
+ case GL_UNPACK_ALIGNMENT:
+ case GL_GENERATE_MIPMAP_HINT:
+ case GL_RED_BITS:
+ case GL_GREEN_BITS:
+ case GL_BLUE_BITS:
+ case GL_ALPHA_BITS:
+ case GL_DEPTH_BITS:
+ case GL_STENCIL_BITS:
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+ case GL_CULL_FACE_MODE:
+ case GL_FRONT_FACE:
+ case GL_ACTIVE_TEXTURE:
+ case GL_STENCIL_FUNC:
+ case GL_STENCIL_VALUE_MASK:
+ case GL_STENCIL_REF:
+ case GL_STENCIL_FAIL:
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ case GL_STENCIL_BACK_FUNC:
+ case GL_STENCIL_BACK_VALUE_MASK:
+ case GL_STENCIL_BACK_REF:
+ case GL_STENCIL_BACK_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ case GL_DEPTH_FUNC:
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ case GL_STENCIL_WRITEMASK:
+ case GL_STENCIL_BACK_WRITEMASK:
+ case GL_STENCIL_CLEAR_VALUE:
+ case GL_SUBPIXEL_BITS:
+ case GL_MAX_TEXTURE_SIZE:
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_RESET_NOTIFICATION_STRATEGY_EXT:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ {
+ if (!getExtensions().packReverseRowOrder)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
+ case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+ {
+ if (!getExtensions().textureRectangle)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ {
+ if ((getClientMajorVersion() < 3) && !getExtensions().drawBuffers)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_VIEWPORT_DIMS:
+ {
+ *type = GL_INT;
+ *numParams = 2;
+ return true;
+ }
+ case GL_VIEWPORT:
+ case GL_SCISSOR_BOX:
+ {
+ *type = GL_INT;
+ *numParams = 4;
+ return true;
+ }
+ case GL_SHADER_COMPILER:
+ case GL_SAMPLE_COVERAGE_INVERT:
+ case GL_DEPTH_WRITEMASK:
+ case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
+ case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
+ case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as
+ // bool-natural
+ case GL_SAMPLE_COVERAGE:
+ case GL_SCISSOR_TEST:
+ case GL_STENCIL_TEST:
+ case GL_DEPTH_TEST:
+ case GL_BLEND:
+ case GL_DITHER:
+ case GL_CONTEXT_ROBUST_ACCESS_EXT:
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ case GL_COLOR_WRITEMASK:
+ {
+ *type = GL_BOOL;
+ *numParams = 4;
+ return true;
+ }
+ case GL_POLYGON_OFFSET_FACTOR:
+ case GL_POLYGON_OFFSET_UNITS:
+ case GL_SAMPLE_COVERAGE_VALUE:
+ case GL_DEPTH_CLEAR_VALUE:
+ case GL_LINE_WIDTH:
+ {
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_DEPTH_RANGE:
+ {
+ *type = GL_FLOAT;
+ *numParams = 2;
+ return true;
+ }
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_BLEND_COLOR:
+ {
+ *type = GL_FLOAT;
+ *numParams = 4;
+ return true;
+ }
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!getExtensions().textureFilterAnisotropic)
+ {
+ return false;
+ }
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ case GL_TIMESTAMP_EXT:
+ if (!getExtensions().disjointTimerQuery)
+ {
+ return false;
+ }
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ case GL_GPU_DISJOINT_EXT:
+ if (!getExtensions().disjointTimerQuery)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_COVERAGE_MODULATION_CHROMIUM:
+ if (!getExtensions().framebufferMixedSamples)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_TEXTURE_BINDING_EXTERNAL_OES:
+ if (!getExtensions().eglStreamConsumerExternal && !getExtensions().eglImageExternal)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (getExtensions().debug)
+ {
+ switch (pname)
+ {
+ case GL_DEBUG_LOGGED_MESSAGES:
+ case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+ case GL_DEBUG_GROUP_STACK_DEPTH:
+ case GL_MAX_DEBUG_MESSAGE_LENGTH:
+ case GL_MAX_DEBUG_LOGGED_MESSAGES:
+ case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+ case GL_MAX_LABEL_LENGTH:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ case GL_DEBUG_OUTPUT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().multisampleCompatibility)
+ {
+ switch (pname)
+ {
+ case GL_MULTISAMPLE_EXT:
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().pathRendering)
+ {
+ switch (pname)
+ {
+ case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
+ case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
+ *type = GL_FLOAT;
+ *numParams = 16;
+ return true;
+ }
+ }
+
+ if (getExtensions().bindGeneratesResource)
+ {
+ switch (pname)
+ {
+ case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().clientArrays)
+ {
+ switch (pname)
+ {
+ case GL_CLIENT_ARRAYS_ANGLE:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().sRGBWriteControl)
+ {
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().robustResourceInitialization &&
+ pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ if (getExtensions().programCacheControl && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
+ switch (pname)
+ {
+ // case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE // equivalent to FRAMEBUFFER_BINDING
+ case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
+ if ((getClientMajorVersion() < 3) && !getExtensions().framebufferBlit)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
+ if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_PROGRAM_BINARY_FORMATS_OES:
+ if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(getCaps().programBinaryFormats.size());
+ return true;
+
+ case GL_PACK_ROW_LENGTH:
+ case GL_PACK_SKIP_ROWS:
+ case GL_PACK_SKIP_PIXELS:
+ if ((getClientMajorVersion() < 3) && !getExtensions().packSubimage)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_UNPACK_ROW_LENGTH:
+ case GL_UNPACK_SKIP_ROWS:
+ case GL_UNPACK_SKIP_PIXELS:
+ if ((getClientMajorVersion() < 3) && !getExtensions().unpackSubimage)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_VERTEX_ARRAY_BINDING:
+ if ((getClientMajorVersion() < 3) && !getExtensions().vertexArrayObject)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_PIXEL_PACK_BUFFER_BINDING:
+ case GL_PIXEL_UNPACK_BUFFER_BINDING:
+ if ((getClientMajorVersion() < 3) && !getExtensions().pixelBufferObject)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_SAMPLES:
+ {
+ static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
+ "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
+ if ((getClientMajorVersion() < 3) && !getExtensions().framebufferMultisample)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+ if ((getClientMajorVersion() < 3) && !getExtensions().standardDerivatives)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ {
+ if ((getClientVersion() < Version(3, 0)) && !getExtensions().drawBuffers)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (getExtensions().multiview && pname == GL_MAX_VIEWS_ANGLE)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (getClientVersion() < Version(3, 0))
+ {
+ return false;
+ }
+
+ // Check for ES3.0+ parameter names
+ switch (pname)
+ {
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ case GL_UNIFORM_BUFFER_BINDING:
+ case GL_TRANSFORM_FEEDBACK_BINDING:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GL_COPY_READ_BUFFER_BINDING:
+ case GL_COPY_WRITE_BUFFER_BINDING:
+ case GL_SAMPLER_BINDING:
+ case GL_READ_BUFFER:
+ case GL_TEXTURE_BINDING_3D:
+ case GL_TEXTURE_BINDING_2D_ARRAY:
+ case GL_MAX_3D_TEXTURE_SIZE:
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+ case GL_MAX_VARYING_COMPONENTS:
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ case GL_MIN_PROGRAM_TEXEL_OFFSET:
+ case GL_MAX_PROGRAM_TEXEL_OFFSET:
+ case GL_NUM_EXTENSIONS:
+ case GL_MAJOR_VERSION:
+ case GL_MINOR_VERSION:
+ case GL_MAX_ELEMENTS_INDICES:
+ case GL_MAX_ELEMENTS_VERTICES:
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+ case GL_UNPACK_IMAGE_HEIGHT:
+ case GL_UNPACK_SKIP_IMAGES:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_MAX_ELEMENT_INDEX:
+ case GL_MAX_UNIFORM_BLOCK_SIZE:
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_TRANSFORM_FEEDBACK_ACTIVE:
+ case GL_TRANSFORM_FEEDBACK_PAUSED:
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ case GL_RASTERIZER_DISCARD:
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_MAX_TEXTURE_LOD_BIAS:
+ {
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getExtensions().requestExtension)
+ {
+ switch (pname)
+ {
+ case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getClientVersion() < Version(3, 1))
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ case GL_DRAW_INDIRECT_BUFFER_BINDING:
+ case GL_MAX_FRAMEBUFFER_WIDTH:
+ case GL_MAX_FRAMEBUFFER_HEIGHT:
+ case GL_MAX_FRAMEBUFFER_SAMPLES:
+ case GL_MAX_SAMPLE_MASK_WORDS:
+ case GL_MAX_COLOR_TEXTURE_SAMPLES:
+ case GL_MAX_DEPTH_TEXTURE_SAMPLES:
+ case GL_MAX_INTEGER_SAMPLES:
+ case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ case GL_MAX_VERTEX_ATTRIB_BINDINGS:
+ case GL_MAX_VERTEX_ATTRIB_STRIDE:
+ case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_VERTEX_ATOMIC_COUNTERS:
+ case GL_MAX_VERTEX_IMAGE_UNIFORMS:
+ case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
+ case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
+ case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
+ case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
+ case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
+ case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
+ case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
+ case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
+ case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
+ case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
+ case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
+ case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
+ case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
+ case GL_MAX_UNIFORM_LOCATIONS:
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
+ case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_COMBINED_ATOMIC_COUNTERS:
+ case GL_MAX_IMAGE_UNITS:
+ case GL_MAX_COMBINED_IMAGE_UNIFORMS:
+ case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
+ case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ case GL_SAMPLE_MASK:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ return false;
+}
+
+bool ValidationContext::getIndexedQueryParameterInfo(GLenum target,
+ GLenum *type,
+ unsigned int *numParams)
+{
+ if (getClientVersion() < Version(3, 0))
+ {
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GL_UNIFORM_BUFFER_BINDING:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GL_UNIFORM_BUFFER_START:
+ case GL_UNIFORM_BUFFER_SIZE:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getClientVersion() < Version(3, 1))
+ {
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+ case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ case GL_VERTEX_BINDING_BUFFER:
+ case GL_VERTEX_BINDING_DIVISOR:
+ case GL_VERTEX_BINDING_OFFSET:
+ case GL_VERTEX_BINDING_STRIDE:
+ case GL_SAMPLE_MASK_VALUE:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_ATOMIC_COUNTER_BUFFER_START:
+ case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+ case GL_SHADER_STORAGE_BUFFER_START:
+ case GL_SHADER_STORAGE_BUFFER_SIZE:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+Program *ValidationContext::getProgram(GLuint handle) const
+{
+ return mState.mShaderPrograms->getProgram(handle);
+}
+
+Shader *ValidationContext::getShader(GLuint handle) const
+{
+ return mState.mShaderPrograms->getShader(handle);
+}
+
+bool ValidationContext::isTextureGenerated(GLuint texture) const
+{
+ return mState.mTextures->isHandleGenerated(texture);
+}
+
+bool ValidationContext::isBufferGenerated(GLuint buffer) const
+{
+ return mState.mBuffers->isHandleGenerated(buffer);
+}
+
+bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const
+{
+ return mState.mRenderbuffers->isHandleGenerated(renderbuffer);
+}
+
+bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const
+{
+ return mState.mFramebuffers->isHandleGenerated(framebuffer);
+}
+
+bool ValidationContext::isProgramPipelineGenerated(GLuint pipeline) const
+{
+ return mState.mPipelines->isHandleGenerated(pipeline);
+}
+
+bool ValidationContext::usingDisplayTextureShareGroup() const
+{
+ return mDisplayTextureShareGroup;
+}
+
+GLenum ValidationContext::getConvertedRenderbufferFormat(GLenum internalformat) const
+{
+ return mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&
+ internalformat == GL_DEPTH_STENCIL
+ ? GL_DEPTH24_STENCIL8
+ : internalformat;
+}
+
+} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/ContextState.h b/src/3rdparty/angle/src/libANGLE/ContextState.h
new file mode 100644
index 0000000000..e6e9f4c6b0
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/ContextState.h
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ContextState: Container class for all GL context state, caps and objects.
+
+#ifndef LIBANGLE_CONTEXTSTATE_H_
+#define LIBANGLE_CONTEXTSTATE_H_
+
+#include "common/MemoryBuffer.h"
+#include "common/angleutils.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/params.h"
+
+namespace gl
+{
+class BufferManager;
+class ContextState;
+class FramebufferManager;
+class PathManager;
+class ProgramPipelineManager;
+class RenderbufferManager;
+class SamplerManager;
+class ShaderProgramManager;
+class SyncManager;
+class TextureManager;
+class ValidationContext;
+
+static constexpr Version ES_2_0 = Version(2, 0);
+static constexpr Version ES_3_0 = Version(3, 0);
+static constexpr Version ES_3_1 = Version(3, 1);
+
+using ContextID = uintptr_t;
+
+class ContextState final : angle::NonCopyable
+{
+ public:
+ ContextState(ContextID context,
+ const ContextState *shareContextState,
+ TextureManager *shareTextures,
+ const Version &clientVersion,
+ State *state,
+ const Caps &caps,
+ const TextureCapsMap &textureCaps,
+ const Extensions &extensions,
+ const Limitations &limitations);
+ ~ContextState();
+
+ ContextID getContextID() const { return mContext; }
+ GLint getClientMajorVersion() const { return mClientVersion.major; }
+ GLint getClientMinorVersion() const { return mClientVersion.minor; }
+ const Version &getClientVersion() const { return mClientVersion; }
+ const State &getState() const { return *mState; }
+ const Caps &getCaps() const { return mCaps; }
+ const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
+ const Extensions &getExtensions() const { return mExtensions; }
+ const Limitations &getLimitations() const { return mLimitations; }
+
+ const TextureCaps &getTextureCap(GLenum internalFormat) const;
+
+ bool usingDisplayTextureShareGroup() const;
+
+ bool isWebGL() const;
+ bool isWebGL1() const;
+
+ private:
+ friend class Context;
+ friend class ValidationContext;
+
+ Version mClientVersion;
+ ContextID mContext;
+ State *mState;
+ const Caps &mCaps;
+ const TextureCapsMap &mTextureCaps;
+ const Extensions &mExtensions;
+ const Limitations &mLimitations;
+
+ BufferManager *mBuffers;
+ ShaderProgramManager *mShaderPrograms;
+ TextureManager *mTextures;
+ RenderbufferManager *mRenderbuffers;
+ SamplerManager *mSamplers;
+ SyncManager *mSyncs;
+ PathManager *mPaths;
+ FramebufferManager *mFramebuffers;
+ ProgramPipelineManager *mPipelines;
+};
+
+class ValidationContext : angle::NonCopyable
+{
+ public:
+ ValidationContext(const ValidationContext *shareContext,
+ TextureManager *shareTextures,
+ const Version &clientVersion,
+ State *state,
+ const Caps &caps,
+ const TextureCapsMap &textureCaps,
+ const Extensions &extensions,
+ const Limitations &limitations,
+ bool skipValidation);
+ virtual ~ValidationContext();
+
+ virtual void handleError(const Error &error) = 0;
+
+ const ContextState &getContextState() const { return mState; }
+ GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
+ GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); }
+ const Version &getClientVersion() const { return mState.getClientVersion(); }
+ const State &getGLState() const { return mState.getState(); }
+ const Caps &getCaps() const { return mState.getCaps(); }
+ const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
+ const Extensions &getExtensions() const { return mState.getExtensions(); }
+ const Limitations &getLimitations() const { return mState.getLimitations(); }
+ bool skipValidation() const { return mSkipValidation; }
+
+ // Specific methods needed for validation.
+ bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
+ bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
+
+ Program *getProgram(GLuint handle) const;
+ Shader *getShader(GLuint handle) const;
+
+ bool isTextureGenerated(GLuint texture) const;
+ bool isBufferGenerated(GLuint buffer) const;
+ bool isRenderbufferGenerated(GLuint renderbuffer) const;
+ bool isFramebufferGenerated(GLuint framebuffer) const;
+ bool isProgramPipelineGenerated(GLuint pipeline) const;
+
+ bool usingDisplayTextureShareGroup() const;
+
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
+
+ bool isWebGL() const { return mState.isWebGL(); }
+ bool isWebGL1() const { return mState.isWebGL1(); }
+
+ template <typename T>
+ const T &getParams() const;
+
+ protected:
+ ContextState mState;
+ bool mSkipValidation;
+ bool mDisplayTextureShareGroup;
+
+ // Caches entry point parameters and values re-used between layers.
+ mutable const ParamTypeInfo *mSavedArgsType;
+ static constexpr size_t kParamsBufferSize = 64u;
+ mutable std::array<uint8_t, kParamsBufferSize> mParamsBuffer;
+};
+
+template <typename T>
+const T &ValidationContext::getParams() const
+{
+ const T *params = reinterpret_cast<T *>(mParamsBuffer.data());
+ ASSERT(mSavedArgsType->hasDynamicType(T::TypeInfo));
+ return *params;
+}
+
+} // namespace gl
+
+#endif // LIBANGLE_CONTEXTSTATE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Data.cpp b/src/3rdparty/angle/src/libANGLE/Data.cpp
deleted file mode 100644
index 83f04b5a0b..0000000000
--- a/src/3rdparty/angle/src/libANGLE/Data.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Data.cpp: Container class for all GL relevant state, caps and objects
-
-#include "libANGLE/Data.h"
-#include "libANGLE/ResourceManager.h"
-
-namespace gl
-{
-
-Data::Data(uintptr_t contextIn,
- GLint clientVersionIn,
- const State &stateIn,
- const Caps &capsIn,
- const TextureCapsMap &textureCapsIn,
- const Extensions &extensionsIn,
- const ResourceManager *resourceManagerIn,
- const Limitations &limitationsIn)
- : context(contextIn),
- clientVersion(clientVersionIn),
- state(&stateIn),
- caps(&capsIn),
- textureCaps(&textureCapsIn),
- extensions(&extensionsIn),
- resourceManager(resourceManagerIn),
- limitations(&limitationsIn)
-{}
-
-Data::~Data()
-{
-}
-
-ValidationContext::ValidationContext(GLint clientVersion,
- const State &state,
- const Caps &caps,
- const TextureCapsMap &textureCaps,
- const Extensions &extensions,
- const ResourceManager *resourceManager,
- const Limitations &limitations,
- bool skipValidation)
- : mData(reinterpret_cast<uintptr_t>(this),
- clientVersion,
- state,
- caps,
- textureCaps,
- extensions,
- resourceManager,
- limitations),
- mSkipValidation(skipValidation)
-{
-}
-} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Data.h b/src/3rdparty/angle/src/libANGLE/Data.h
deleted file mode 100644
index f7230d74bc..0000000000
--- a/src/3rdparty/angle/src/libANGLE/Data.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Data.h: Container class for all GL relevant state, caps and objects
-
-#ifndef LIBANGLE_DATA_H_
-#define LIBANGLE_DATA_H_
-
-#include "common/angleutils.h"
-#include "libANGLE/State.h"
-
-namespace gl
-{
-
-struct Data final : public angle::NonCopyable
-{
- public:
- Data(uintptr_t context,
- GLint clientVersion,
- const State &state,
- const Caps &caps,
- const TextureCapsMap &textureCaps,
- const Extensions &extensions,
- const ResourceManager *resourceManager,
- const Limitations &limitations);
- ~Data();
-
- uintptr_t context;
- GLint clientVersion;
- const State *state;
- const Caps *caps;
- const TextureCapsMap *textureCaps;
- const Extensions *extensions;
- const ResourceManager *resourceManager;
- const Limitations *limitations;
-};
-
-class ValidationContext : angle::NonCopyable
-{
- public:
- ValidationContext(GLint clientVersion,
- const State &state,
- const Caps &caps,
- const TextureCapsMap &textureCaps,
- const Extensions &extensions,
- const ResourceManager *resourceManager,
- const Limitations &limitations,
- bool skipValidation);
- virtual ~ValidationContext() {}
-
- virtual void recordError(const Error &error) = 0;
-
- const Data &getData() const { return mData; }
- int getClientVersion() const { return mData.clientVersion; }
- const State &getState() const { return *mData.state; }
- const Caps &getCaps() const { return *mData.caps; }
- const TextureCapsMap &getTextureCaps() const { return *mData.textureCaps; }
- const Extensions &getExtensions() const { return *mData.extensions; }
- const Limitations &getLimitations() const { return *mData.limitations; }
- bool skipValidation() const { return mSkipValidation; }
-
- protected:
- Data mData;
- bool mSkipValidation;
-};
-
-}
-
-#endif // LIBANGLE_DATA_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Debug.cpp b/src/3rdparty/angle/src/libANGLE/Debug.cpp
index 30321f4160..96f30df98c 100644
--- a/src/3rdparty/angle/src/libANGLE/Debug.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Debug.cpp
@@ -16,6 +16,26 @@
namespace gl
{
+Debug::Control::Control()
+{
+}
+
+Debug::Control::~Control()
+{
+}
+
+Debug::Control::Control(const Control &other) = default;
+
+Debug::Group::Group()
+{
+}
+
+Debug::Group::~Group()
+{
+}
+
+Debug::Group::Group(const Group &other) = default;
+
Debug::Debug()
: mOutputEnabled(false),
mCallbackFunction(nullptr),
@@ -28,6 +48,10 @@ Debug::Debug()
pushDefaultGroup();
}
+Debug::~Debug()
+{
+}
+
void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
{
mMaxLoggedMessages = maxLoggedMessages;
diff --git a/src/3rdparty/angle/src/libANGLE/Debug.h b/src/3rdparty/angle/src/libANGLE/Debug.h
index f545b815e4..2c15c25e9a 100644
--- a/src/3rdparty/angle/src/libANGLE/Debug.h
+++ b/src/3rdparty/angle/src/libANGLE/Debug.h
@@ -31,6 +31,7 @@ class Debug : angle::NonCopyable
{
public:
Debug();
+ ~Debug();
void setMaxLoggedMessages(GLuint maxLoggedMessages);
@@ -91,6 +92,10 @@ class Debug : angle::NonCopyable
struct Control
{
+ Control();
+ ~Control();
+ Control(const Control &other);
+
GLenum source;
GLenum type;
GLenum severity;
@@ -100,6 +105,10 @@ class Debug : angle::NonCopyable
struct Group
{
+ Group();
+ ~Group();
+ Group(const Group &other);
+
GLenum source;
GLuint id;
std::string message;
diff --git a/src/3rdparty/angle/src/libANGLE/Device.cpp b/src/3rdparty/angle/src/libANGLE/Device.cpp
index eb30b2023f..3ebf48b919 100644
--- a/src/3rdparty/angle/src/libANGLE/Device.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Device.cpp
@@ -45,33 +45,28 @@ static DeviceSet *GetDeviceSet()
// Static factory methods
egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice)
{
+ *outDevice = nullptr;
+
#if defined(ANGLE_ENABLE_D3D11)
if (deviceType == EGL_D3D11_DEVICE_ANGLE)
{
- rx::DeviceD3D *deviceD3D = new rx::DeviceD3D();
- egl::Error error = deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE);
- if (error.isError())
- {
- *outDevice = nullptr;
- return error;
- }
-
- *outDevice = new Device(nullptr, deviceD3D);
+ std::unique_ptr<rx::DeviceD3D> deviceD3D(new rx::DeviceD3D());
+ ANGLE_TRY(deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE));
+ *outDevice = new Device(nullptr, deviceD3D.release());
GetDeviceSet()->insert(*outDevice);
- return egl::Error(EGL_SUCCESS);
+ return NoError();
}
#endif
// Note that creating an EGL device from inputted D3D9 parameters isn't currently supported
- *outDevice = nullptr;
- return egl::Error(EGL_BAD_ATTRIBUTE);
+ return EglBadAttribute();
}
egl::Error Device::CreateDevice(Display *owningDisplay, rx::DeviceImpl *impl, Device **outDevice)
{
*outDevice = new Device(owningDisplay, impl);
GetDeviceSet()->insert(*outDevice);
- return egl::Error(EGL_SUCCESS);
+ return NoError();
}
bool Device::IsValidDevice(Device *device)
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp
index 486c74abc0..735b472787 100644
--- a/src/3rdparty/angle/src/libANGLE/Display.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Display.cpp
@@ -28,6 +28,8 @@
#include "libANGLE/histogram_macros.h"
#include "libANGLE/Image.h"
#include "libANGLE/Surface.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/ResourceManager.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/ImageImpl.h"
#include "third_party/trace_event/trace_event.h"
@@ -43,38 +45,34 @@
# include "libANGLE/renderer/gl/glx/DisplayGLX.h"
# elif defined(ANGLE_PLATFORM_APPLE)
# include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
+# elif defined(ANGLE_USE_OZONE)
+# include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h"
+# elif defined(ANGLE_PLATFORM_ANDROID)
+# include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
# else
# error Unsupported OpenGL platform.
# endif
#endif
-namespace egl
-{
+#if defined(ANGLE_ENABLE_NULL)
+#include "libANGLE/renderer/null/DisplayNULL.h"
+#endif // defined(ANGLE_ENABLE_NULL)
-namespace
-{
+#if defined(ANGLE_ENABLE_VULKAN)
+#if defined(ANGLE_PLATFORM_WINDOWS)
+#include "libANGLE/renderer/vulkan/win32/DisplayVkWin32.h"
+#elif defined(ANGLE_PLATFORM_LINUX)
+#include "libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h"
+#else
+#error Unsupported Vulkan platform.
+#endif
+#endif // defined(ANGLE_ENABLE_VULKAN)
-class DefaultPlatform : public angle::Platform
+namespace egl
{
-public:
- DefaultPlatform() {}
- ~DefaultPlatform() override {}
-};
-DefaultPlatform *defaultPlatform = nullptr;
-
-void InitDefaultPlatformImpl()
+namespace
{
- if (ANGLEPlatformCurrent() == nullptr)
- {
- if (defaultPlatform == nullptr)
- {
- defaultPlatform = new DefaultPlatform();
- }
-
- ANGLEPlatformInitialize(defaultPlatform);
- }
-}
typedef std::map<EGLNativeWindowType, Surface*> WindowSurfaceMap;
// Get a map of all EGL window surfaces to validate that no window has more than one EGL surface
@@ -99,7 +97,7 @@ static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap()
return &displays;
}
-rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice)
+rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state)
{
rx::DisplayImpl *impl = nullptr;
@@ -107,7 +105,7 @@ rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice)
{
#if defined(ANGLE_ENABLE_D3D11)
case EGL_D3D11_DEVICE_ANGLE:
- impl = new rx::DisplayD3D();
+ impl = new rx::DisplayD3D(state);
break;
#endif
#if defined(ANGLE_ENABLE_D3D9)
@@ -130,86 +128,162 @@ rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice)
return impl;
}
-rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap)
+rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap, const DisplayState &state)
{
rx::DisplayImpl *impl = nullptr;
- EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ EGLAttrib displayType =
+ attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
switch (displayType)
{
- case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
- // Default to D3D displays
- impl = new rx::DisplayD3D();
+ // Default to D3D displays
+ impl = new rx::DisplayD3D(state);
#elif defined(ANGLE_USE_X11)
- impl = new rx::DisplayGLX();
+ impl = new rx::DisplayGLX(state);
#elif defined(ANGLE_PLATFORM_APPLE)
- impl = new rx::DisplayCGL();
+ impl = new rx::DisplayCGL(state);
+#elif defined(ANGLE_USE_OZONE)
+ impl = new rx::DisplayOzone(state);
+#elif defined(ANGLE_PLATFORM_ANDROID)
+ impl = new rx::DisplayAndroid(state);
#else
- // No display available
- UNREACHABLE();
+ // No display available
+ UNREACHABLE();
#endif
- break;
+ break;
- case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
- impl = new rx::DisplayD3D();
+ impl = new rx::DisplayD3D(state);
#else
- // A D3D display was requested on a platform that doesn't support it
- UNREACHABLE();
+ // A D3D display was requested on a platform that doesn't support it
+ UNREACHABLE();
#endif
- break;
+ break;
- case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
#if defined(ANGLE_ENABLE_OPENGL)
#if defined(ANGLE_PLATFORM_WINDOWS)
- impl = new rx::DisplayWGL();
+ impl = new rx::DisplayWGL(state);
#elif defined(ANGLE_USE_X11)
- impl = new rx::DisplayGLX();
+ impl = new rx::DisplayGLX(state);
#elif defined(ANGLE_PLATFORM_APPLE)
- impl = new rx::DisplayCGL();
+ impl = new rx::DisplayCGL(state);
+#elif defined(ANGLE_USE_OZONE)
+ // This might work but has never been tried, so disallow for now.
+ impl = nullptr;
+#elif defined(ANGLE_PLATFORM_ANDROID)
+ // No GL support on this platform, fail display creation.
+ impl = nullptr;
#else
#error Unsupported OpenGL platform.
#endif
#else
- UNREACHABLE();
-#endif
- break;
+ // No display available
+ UNREACHABLE();
+#endif // defined(ANGLE_ENABLE_OPENGL)
+ break;
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
#if defined(ANGLE_ENABLE_OPENGL)
- case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
#if defined(ANGLE_PLATFORM_WINDOWS)
- impl = new rx::DisplayWGL();
+ impl = new rx::DisplayWGL(state);
#elif defined(ANGLE_USE_X11)
- impl = new rx::DisplayGLX();
+ impl = new rx::DisplayGLX(state);
+#elif defined(ANGLE_USE_OZONE)
+ impl = new rx::DisplayOzone(state);
+#elif defined(ANGLE_PLATFORM_ANDROID)
+ impl = new rx::DisplayAndroid(state);
#else
- // No GLES support on this platform, fail display creation.
- impl = nullptr;
+ // No GLES support on this platform, fail display creation.
+ impl = nullptr;
#endif
- break;
+#endif // defined(ANGLE_ENABLE_OPENGL)
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
+#if defined(ANGLE_ENABLE_VULKAN)
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ impl = new rx::DisplayVkWin32(state);
+#elif defined(ANGLE_PLATFORM_LINUX)
+ impl = new rx::DisplayVkXcb(state);
+#else
+#error Unsupported Vulkan platform.
#endif
+#else
+ // No display available
+ UNREACHABLE();
+#endif // defined(ANGLE_ENABLE_VULKAN)
+ break;
- default:
- UNREACHABLE();
- break;
+ case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
+#if defined(ANGLE_ENABLE_NULL)
+ impl = new rx::DisplayNULL(state);
+#else
+ // No display available
+ UNREACHABLE();
+#endif // defined(ANGLE_ENABLE_NULL)
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
}
return impl;
}
+void Display_logError(angle::PlatformMethods *platform, const char *errorMessage)
+{
+ gl::Trace(gl::LOG_ERR, errorMessage);
}
-Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap)
+void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage)
{
- // Initialize the global platform if not already
- InitDefaultPlatformImpl();
+ gl::Trace(gl::LOG_WARN, warningMessage);
+}
- Display *display = nullptr;
+void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage)
+{
+ // Uncomment to get info spam
+ // gl::Trace(gl::LOG_WARN, infoMessage);
+}
+
+void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display)
+{
+ angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent();
+ if (platformMethods->logError != angle::DefaultLogError)
+ {
+ // Don't reset pre-set Platform to Default
+ return;
+ }
+
+ ANGLEResetDisplayPlatform(display);
+ platformMethods->logError = Display_logError;
+ platformMethods->logWarning = Display_logWarning;
+ platformMethods->logInfo = Display_logInfo;
+}
+
+} // anonymous namespace
- EGLNativeDisplayType displayId = reinterpret_cast<EGLNativeDisplayType>(native_display);
+DisplayState::DisplayState()
+{
+}
+
+DisplayState::~DisplayState()
+{
+}
- ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
- ANGLEPlatformDisplayMap::const_iterator iter = displays->find(displayId);
+// static
+Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
+ const AttributeMap &attribMap)
+{
+ Display *display = nullptr;
+
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
+ const auto &iter = displays->find(nativeDisplay);
if (iter != displays->end())
{
display = iter->second;
@@ -218,19 +292,19 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap
if (display == nullptr)
{
// Validate the native display
- if (!Display::isValidNativeDisplay(displayId))
+ if (!Display::isValidNativeDisplay(nativeDisplay))
{
- return NULL;
+ return nullptr;
}
- display = new Display(EGL_PLATFORM_ANGLE_ANGLE, displayId, nullptr);
- displays->insert(std::make_pair(displayId, display));
+ display = new Display(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, nullptr);
+ displays->insert(std::make_pair(nativeDisplay, display));
}
// Apply new attributes if the display is not initialized yet.
if (!display->isInitialized())
{
- rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap);
+ rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap, display->getState());
if (impl == nullptr)
{
// No valid display implementation for these attributes
@@ -243,15 +317,12 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap
return display;
}
-Display *Display::GetDisplayFromDevice(void *native_display)
+// static
+Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap)
{
- // Initialize the global platform if not already
- InitDefaultPlatformImpl();
-
Display *display = nullptr;
- Device *eglDevice = reinterpret_cast<Device *>(native_display);
- ASSERT(Device::IsValidDevice(eglDevice));
+ ASSERT(Device::IsValidDevice(device));
ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap();
DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap();
@@ -260,7 +331,7 @@ Display *Display::GetDisplayFromDevice(void *native_display)
for (auto &displayMapEntry : *anglePlatformDisplays)
{
egl::Display *iterDisplay = displayMapEntry.second;
- if (iterDisplay->getDevice() == eglDevice)
+ if (iterDisplay->getDevice() == device)
{
display = iterDisplay;
}
@@ -269,7 +340,7 @@ Display *Display::GetDisplayFromDevice(void *native_display)
if (display == nullptr)
{
// See if the eglDevice is in use by a Display created using the DEVICE platform
- DevicePlatformDisplayMap::const_iterator iter = devicePlatformDisplays->find(eglDevice);
+ const auto &iter = devicePlatformDisplays->find(device);
if (iter != devicePlatformDisplays->end())
{
display = iter->second;
@@ -279,15 +350,15 @@ Display *Display::GetDisplayFromDevice(void *native_display)
if (display == nullptr)
{
// Otherwise create a new Display
- display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, eglDevice);
- devicePlatformDisplays->insert(std::make_pair(eglDevice, display));
+ display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device);
+ devicePlatformDisplays->insert(std::make_pair(device, display));
}
// Apply new attributes if the display is not initialized yet.
if (!display->isInitialized())
{
- rx::DisplayImpl *impl = CreateDisplayFromDevice(eglDevice);
- display->setAttributes(impl, egl::AttributeMap());
+ rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState());
+ display->setAttributes(impl, attribMap);
}
return display;
@@ -299,19 +370,26 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe
mAttributeMap(),
mConfigSet(),
mContextSet(),
+ mStreamSet(),
mInitialized(false),
+ mDeviceLost(false),
mCaps(),
mDisplayExtensions(),
mDisplayExtensionString(),
mVendorString(),
mDevice(eglDevice),
- mPlatform(platform)
+ mPlatform(platform),
+ mTextureManager(nullptr),
+ mMemoryProgramCache(gl::kDefaultMaxProgramCacheMemoryBytes),
+ mGlobalTextureShareGroupUsers(0),
+ mProxyContext(this)
{
}
Display::~Display()
{
- terminate();
+ // TODO(jmadill): When is this called?
+ // terminate();
if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE)
{
@@ -336,6 +414,8 @@ Display::~Display()
UNREACHABLE();
}
+ mProxyContext.reset(nullptr);
+
SafeDelete(mDevice);
SafeDelete(mImplementation);
}
@@ -353,8 +433,20 @@ void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap
Error Display::initialize()
{
- // Re-initialize default platform if it's needed
- InitDefaultPlatformImpl();
+ // TODO(jmadill): Store Platform in Display and init here.
+ const angle::PlatformMethods *platformMethods =
+ reinterpret_cast<const angle::PlatformMethods *>(
+ mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0));
+ if (platformMethods != nullptr)
+ {
+ *ANGLEPlatformCurrent() = *platformMethods;
+ }
+ else
+ {
+ ANGLESetDefaultDisplayPlatform(this);
+ }
+
+ gl::InitializeDebugAnnotations(&mAnnotator);
SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.DisplayInitializeMS");
TRACE_EVENT0("gpu.angle", "egl::Display::initialize");
@@ -363,17 +455,14 @@ Error Display::initialize()
if (isInitialized())
{
- return Error(EGL_SUCCESS);
+ return NoError();
}
Error error = mImplementation->initialize(this);
if (error.isError())
{
// Log extended error message here
- std::stringstream errorStream;
- errorStream << "ANGLE Display::initialize error " << error.getID() << ": "
- << error.getMessage();
- ANGLEPlatformCurrent()->logError(errorStream.str().c_str());
+ ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage();
return error;
}
@@ -383,7 +472,7 @@ Error Display::initialize()
if (mConfigSet.size() == 0)
{
mImplementation->terminate();
- return Error(EGL_NOT_INITIALIZED);
+ return EglNotInitialized();
}
initDisplayExtensions();
@@ -395,17 +484,8 @@ Error Display::initialize()
if (mDisplayExtensions.deviceQuery)
{
rx::DeviceImpl *impl = nullptr;
- error = mImplementation->getDevice(&impl);
- if (error.isError())
- {
- return error;
- }
-
- error = Device::CreateDevice(this, impl, &mDevice);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(mImplementation->getDevice(&impl));
+ ANGLE_TRY(Device::CreateDevice(this, impl, &mDevice));
}
else
{
@@ -419,28 +499,45 @@ Error Display::initialize()
ASSERT(mDevice != nullptr);
}
+ mProxyContext.reset(nullptr);
+ gl::Context *proxyContext = new gl::Context(mImplementation, nullptr, nullptr, nullptr, nullptr,
+ egl::AttributeMap(), mDisplayExtensions);
+ mProxyContext.reset(proxyContext);
+
mInitialized = true;
- return Error(EGL_SUCCESS);
+ return NoError();
}
-void Display::terminate()
+Error Display::terminate()
{
- makeCurrent(nullptr, nullptr, nullptr);
+ ANGLE_TRY(makeCurrent(nullptr, nullptr, nullptr));
+
+ mMemoryProgramCache.clear();
+
+ mProxyContext.reset(nullptr);
while (!mContextSet.empty())
{
- destroyContext(*mContextSet.begin());
+ ANGLE_TRY(destroyContext(*mContextSet.begin()));
}
+ // The global texture manager should be deleted with the last context that uses it.
+ ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr);
+
while (!mImageSet.empty())
{
destroyImage(*mImageSet.begin());
}
- while (!mImplementation->getSurfaceSet().empty())
+ while (!mStreamSet.empty())
{
- destroySurface(*mImplementation->getSurfaceSet().begin());
+ destroyStream(*mStreamSet.begin());
+ }
+
+ while (!mState.surfaceSet.empty())
+ {
+ ANGLE_TRY(destroySurface(*mState.surfaceSet.begin()));
}
mConfigSet.clear();
@@ -454,9 +551,16 @@ void Display::terminate()
mImplementation->terminate();
+ mDeviceLost = false;
+
mInitialized = false;
- // Never de-init default platform.. terminate is not that final.
+ gl::UninitializeDebugAnnotations();
+
+ // TODO(jmadill): Store Platform in Display and deinit here.
+ ANGLEResetDisplayPlatform(this);
+
+ return NoError();
}
std::vector<const Config*> Display::getConfigs(const egl::AttributeMap &attribs) const
@@ -464,189 +568,100 @@ std::vector<const Config*> Display::getConfigs(const egl::AttributeMap &attribs)
return mConfigSet.filter(attribs);
}
-bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value)
-{
- switch (attribute)
- {
- case EGL_BUFFER_SIZE: *value = configuration->bufferSize; break;
- case EGL_ALPHA_SIZE: *value = configuration->alphaSize; break;
- case EGL_BLUE_SIZE: *value = configuration->blueSize; break;
- case EGL_GREEN_SIZE: *value = configuration->greenSize; break;
- case EGL_RED_SIZE: *value = configuration->redSize; break;
- case EGL_DEPTH_SIZE: *value = configuration->depthSize; break;
- case EGL_STENCIL_SIZE: *value = configuration->stencilSize; break;
- case EGL_CONFIG_CAVEAT: *value = configuration->configCaveat; break;
- case EGL_CONFIG_ID: *value = configuration->configID; break;
- case EGL_LEVEL: *value = configuration->level; break;
- case EGL_NATIVE_RENDERABLE: *value = configuration->nativeRenderable; break;
- case EGL_NATIVE_VISUAL_ID: *value = configuration->nativeVisualID; break;
- case EGL_NATIVE_VISUAL_TYPE: *value = configuration->nativeVisualType; break;
- case EGL_SAMPLES: *value = configuration->samples; break;
- case EGL_SAMPLE_BUFFERS: *value = configuration->sampleBuffers; break;
- case EGL_SURFACE_TYPE: *value = configuration->surfaceType; break;
- case EGL_TRANSPARENT_TYPE: *value = configuration->transparentType; break;
- case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->transparentBlueValue; break;
- case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->transparentGreenValue; break;
- case EGL_TRANSPARENT_RED_VALUE: *value = configuration->transparentRedValue; break;
- case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->bindToTextureRGB; break;
- case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->bindToTextureRGBA; break;
- case EGL_MIN_SWAP_INTERVAL: *value = configuration->minSwapInterval; break;
- case EGL_MAX_SWAP_INTERVAL: *value = configuration->maxSwapInterval; break;
- case EGL_LUMINANCE_SIZE: *value = configuration->luminanceSize; break;
- case EGL_ALPHA_MASK_SIZE: *value = configuration->alphaMaskSize; break;
- case EGL_COLOR_BUFFER_TYPE: *value = configuration->colorBufferType; break;
- case EGL_RENDERABLE_TYPE: *value = configuration->renderableType; break;
- case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break;
- case EGL_CONFORMANT: *value = configuration->conformant; break;
- case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break;
- case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break;
- case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break;
-
- case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
- if (!getExtensions().surfaceOrientation)
- {
- return false;
- }
- *value = configuration->optimalOrientation;
- break;
-
- default:
- return false;
- }
-
- return true;
-}
-
-Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
+Error Display::createWindowSurface(const Config *configuration,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
Surface **outSurface)
{
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(restoreLostDevice());
}
- rx::SurfaceImpl *surfaceImpl = mImplementation->createWindowSurface(configuration, window, attribs);
- ASSERT(surfaceImpl != nullptr);
-
- Error error = surfaceImpl->initialize();
- if (error.isError())
- {
- SafeDelete(surfaceImpl);
- return error;
- }
+ SurfacePointer surface(new WindowSurface(mImplementation, configuration, window, attribs),
+ this);
+ ANGLE_TRY(surface->initialize(this));
- Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs);
- mImplementation->getSurfaceSet().insert(surface);
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end());
- windowSurfaces->insert(std::make_pair(window, surface));
+ windowSurfaces->insert(std::make_pair(window, *outSurface));
- ASSERT(outSurface != nullptr);
- *outSurface = surface;
- return Error(EGL_SUCCESS);
+ return NoError();
}
-Error Display::createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface)
+Error Display::createPbufferSurface(const Config *configuration,
+ const AttributeMap &attribs,
+ Surface **outSurface)
{
ASSERT(isInitialized());
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
- }
-
- rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferSurface(configuration, attribs);
- ASSERT(surfaceImpl != nullptr);
-
- Error error = surfaceImpl->initialize();
- if (error.isError())
- {
- SafeDelete(surfaceImpl);
- return error;
+ ANGLE_TRY(restoreLostDevice());
}
- Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs);
- mImplementation->getSurfaceSet().insert(surface);
+ SurfacePointer surface(new PbufferSurface(mImplementation, configuration, attribs), this);
+ ANGLE_TRY(surface->initialize(this));
ASSERT(outSurface != nullptr);
- *outSurface = surface;
- return Error(EGL_SUCCESS);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
}
-Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle,
- const AttributeMap &attribs, Surface **outSurface)
+Error Display::createPbufferFromClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
+ Surface **outSurface)
{
ASSERT(isInitialized());
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
- }
-
- rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs);
- ASSERT(surfaceImpl != nullptr);
-
- Error error = surfaceImpl->initialize();
- if (error.isError())
- {
- SafeDelete(surfaceImpl);
- return error;
+ ANGLE_TRY(restoreLostDevice());
}
- Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs);
- mImplementation->getSurfaceSet().insert(surface);
+ SurfacePointer surface(
+ new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs), this);
+ ANGLE_TRY(surface->initialize(this));
ASSERT(outSurface != nullptr);
- *outSurface = surface;
- return Error(EGL_SUCCESS);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
}
-Error Display::createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
+Error Display::createPixmapSurface(const Config *configuration,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
Surface **outSurface)
{
ASSERT(isInitialized());
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(restoreLostDevice());
}
- rx::SurfaceImpl *surfaceImpl = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs);
- ASSERT(surfaceImpl != nullptr);
-
- Error error = surfaceImpl->initialize();
- if (error.isError())
- {
- SafeDelete(surfaceImpl);
- return error;
- }
-
- Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs);
- mImplementation->getSurfaceSet().insert(surface);
+ SurfacePointer surface(new PixmapSurface(mImplementation, configuration, nativePixmap, attribs),
+ this);
+ ANGLE_TRY(surface->initialize(this));
ASSERT(outSurface != nullptr);
- *outSurface = surface;
- return Error(EGL_SUCCESS);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
}
-Error Display::createImage(gl::Context *context,
+Error Display::createImage(const gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const AttributeMap &attribs,
@@ -656,11 +671,7 @@ Error Display::createImage(gl::Context *context,
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(restoreLostDevice());
}
egl::ImageSibling *sibling = nullptr;
@@ -678,16 +689,11 @@ Error Display::createImage(gl::Context *context,
}
ASSERT(sibling != nullptr);
- rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs);
- ASSERT(imageImpl != nullptr);
+ angle::UniqueObjectPointer<Image, gl::Context> imagePtr(
+ new Image(mImplementation, target, sibling, attribs), context);
+ ANGLE_TRY(imagePtr->initialize());
- Error error = imageImpl->initialize();
- if (error.isError())
- {
- return error;
- }
-
- Image *image = new Image(imageImpl, target, sibling, attribs);
+ Image *image = imagePtr.release();
ASSERT(outImage != nullptr);
*outImage = image;
@@ -696,49 +702,92 @@ Error Display::createImage(gl::Context *context,
image->addRef();
mImageSet.insert(image);
- return Error(EGL_SUCCESS);
+ return NoError();
+}
+
+Error Display::createStream(const AttributeMap &attribs, Stream **outStream)
+{
+ ASSERT(isInitialized());
+
+ Stream *stream = new Stream(this, attribs);
+
+ ASSERT(stream != nullptr);
+ mStreamSet.insert(stream);
+
+ ASSERT(outStream != nullptr);
+ *outStream = stream;
+
+ return NoError();
}
-Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs,
+Error Display::createContext(const Config *configuration,
+ gl::Context *shareContext,
+ const AttributeMap &attribs,
gl::Context **outContext)
{
ASSERT(isInitialized());
if (mImplementation->testDeviceLost())
{
- Error error = restoreLostDevice();
- if (error.isError())
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ // This display texture sharing will allow the first context to create the texture share group.
+ bool usingDisplayTextureShareGroup =
+ attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
+ gl::TextureManager *shareTextures = nullptr;
+
+ if (usingDisplayTextureShareGroup)
+ {
+ ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0));
+ if (mTextureManager == nullptr)
{
- return error;
+ mTextureManager = new gl::TextureManager();
}
+
+ mGlobalTextureShareGroupUsers++;
+ shareTextures = mTextureManager;
}
- gl::Context *context = *outContext =
- mImplementation->createContext(configuration, shareContext, attribs);
+ gl::MemoryProgramCache *cachePointer = &mMemoryProgramCache;
+
+ // Check context creation attributes to see if we should enable the cache.
+ if (mAttributeMap.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, EGL_TRUE) == EGL_FALSE)
+ {
+ cachePointer = nullptr;
+ }
+
+ // A program cache size of zero indicates it should be disabled.
+ if (mMemoryProgramCache.maxSize() == 0)
+ {
+ cachePointer = nullptr;
+ }
+
+ gl::Context *context =
+ new gl::Context(mImplementation, configuration, shareContext, shareTextures, cachePointer,
+ attribs, mDisplayExtensions);
ASSERT(context != nullptr);
mContextSet.insert(context);
ASSERT(outContext != nullptr);
*outContext = context;
- return Error(EGL_SUCCESS);
+ return NoError();
}
-Error Display::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
+Error Display::makeCurrent(egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context)
{
- Error error = mImplementation->makeCurrent(drawSurface, readSurface, context);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(mImplementation->makeCurrent(drawSurface, readSurface, context));
- if (context != nullptr && drawSurface != nullptr)
+ if (context != nullptr)
{
ASSERT(readSurface == drawSurface);
- context->makeCurrent(drawSurface);
+ ANGLE_TRY(context->makeCurrent(this, drawSurface));
}
- return egl::Error(EGL_SUCCESS);
+ return NoError();
}
Error Display::restoreLostDevice()
@@ -748,14 +797,14 @@ Error Display::restoreLostDevice()
if ((*ctx)->isResetNotificationEnabled())
{
// If reset notifications have been requested, application must delete all contexts first
- return Error(EGL_CONTEXT_LOST);
+ return EglContextLost();
}
}
- return mImplementation->restoreLostDevice();
+ return mImplementation->restoreLostDevice(this);
}
-void Display::destroySurface(Surface *surface)
+Error Display::destroySurface(Surface *surface)
{
if (surface->getType() == EGL_WINDOW_BIT)
{
@@ -774,54 +823,89 @@ void Display::destroySurface(Surface *surface)
}
ASSERT(surfaceRemoved);
- UNUSED_ASSERTION_VARIABLE(surfaceRemoved);
}
- mImplementation->destroySurface(surface);
+ mState.surfaceSet.erase(surface);
+ ANGLE_TRY(surface->onDestroy(this));
+ return NoError();
}
void Display::destroyImage(egl::Image *image)
{
auto iter = mImageSet.find(image);
ASSERT(iter != mImageSet.end());
- (*iter)->release();
+ (*iter)->release(mProxyContext.get());
mImageSet.erase(iter);
}
-void Display::destroyContext(gl::Context *context)
+void Display::destroyStream(egl::Stream *stream)
{
+ mStreamSet.erase(stream);
+ SafeDelete(stream);
+}
+
+Error Display::destroyContext(gl::Context *context)
+{
+ if (context->usingDisplayTextureShareGroup())
+ {
+ ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr);
+ if (mGlobalTextureShareGroupUsers == 1)
+ {
+ // If this is the last context using the global share group, destroy the global texture
+ // manager so that the textures can be destroyed while a context still exists
+ mTextureManager->release(context);
+ mTextureManager = nullptr;
+ }
+ mGlobalTextureShareGroupUsers--;
+ }
+
+ ANGLE_TRY(context->onDestroy(this));
mContextSet.erase(context);
SafeDelete(context);
+ return NoError();
}
bool Display::isDeviceLost() const
{
ASSERT(isInitialized());
- return mImplementation->isDeviceLost();
+ return mDeviceLost;
}
bool Display::testDeviceLost()
{
ASSERT(isInitialized());
- return mImplementation->testDeviceLost();
+
+ if (!mDeviceLost && mImplementation->testDeviceLost())
+ {
+ notifyDeviceLost();
+ }
+
+ return mDeviceLost;
}
void Display::notifyDeviceLost()
{
+ if (mDeviceLost)
+ {
+ return;
+ }
+
for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
{
(*context)->markContextLost();
}
+
+ mDeviceLost = true;
}
-Error Display::waitClient() const
+Error Display::waitClient(const gl::Context *context) const
{
- return mImplementation->waitClient();
+ return mImplementation->waitClient(context);
}
-Error Display::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const
+Error Display::waitNative(const gl::Context *context, EGLint engine) const
{
- return mImplementation->waitNative(engine, drawSurface, readSurface);
+ return mImplementation->waitNative(context, engine);
}
const Caps &Display::getCaps() const
@@ -839,14 +923,14 @@ bool Display::isValidConfig(const Config *config) const
return mConfigSet.contains(config);
}
-bool Display::isValidContext(gl::Context *context) const
+bool Display::isValidContext(const gl::Context *context) const
{
- return mContextSet.find(context) != mContextSet.end();
+ return mContextSet.find(const_cast<gl::Context *>(context)) != mContextSet.end();
}
-bool Display::isValidSurface(Surface *surface) const
+bool Display::isValidSurface(const Surface *surface) const
{
- return mImplementation->getSurfaceSet().find(surface) != mImplementation->getSurfaceSet().end();
+ return mState.surfaceSet.find(const_cast<Surface *>(surface)) != mState.surfaceSet.end();
}
bool Display::isValidImage(const Image *image) const
@@ -854,6 +938,11 @@ bool Display::isValidImage(const Image *image) const
return mImageSet.find(const_cast<Image *>(image)) != mImageSet.end();
}
+bool Display::isValidStream(const Stream *stream) const
+{
+ return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end();
+}
+
bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{
WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
@@ -879,12 +968,20 @@ static ClientExtensions GenerateClientExtensions()
extensions.platformANGLEOpenGL = true;
#endif
+#if defined(ANGLE_ENABLE_NULL)
+ extensions.platformANGLENULL = true;
+#endif
+
#if defined(ANGLE_ENABLE_D3D11)
extensions.deviceCreation = true;
extensions.deviceCreationD3D11 = true;
extensions.experimentalPresentPath = true;
#endif
+#if defined(ANGLE_ENABLE_VULKAN)
+ extensions.platformANGLEVulkan = true;
+#endif
+
#if defined(ANGLE_USE_X11)
extensions.x11Visual = true;
#endif
@@ -904,15 +1001,18 @@ static std::string GenerateExtensionsString(const T &extensions)
return stream.str();
}
-const ClientExtensions &Display::getClientExtensions()
+// static
+const ClientExtensions &Display::GetClientExtensions()
{
static const ClientExtensions clientExtensions = GenerateClientExtensions();
return clientExtensions;
}
-const std::string &Display::getClientExtensionString()
+// static
+const std::string &Display::GetClientExtensionString()
{
- static const std::string clientExtensionsString = GenerateExtensionsString(getClientExtensions());
+ static const std::string clientExtensionsString =
+ GenerateExtensionsString(GetClientExtensions());
return clientExtensionsString;
}
@@ -920,9 +1020,20 @@ void Display::initDisplayExtensions()
{
mDisplayExtensions = mImplementation->getExtensions();
+ // Some extensions are always available because they are implemented in the EGL layer.
+ mDisplayExtensions.createContext = true;
+ mDisplayExtensions.createContextNoError = true;
+ mDisplayExtensions.createContextWebGLCompatibility = true;
+ mDisplayExtensions.createContextBindGeneratesResource = true;
+ mDisplayExtensions.createContextClientArrays = true;
+ mDisplayExtensions.pixelFormatFloat = true;
+
// Force EGL_KHR_get_all_proc_addresses on.
mDisplayExtensions.getAllProcAddresses = true;
+ // Enable program cache control since it is not back-end dependent.
+ mDisplayExtensions.programCacheControl = true;
+
mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
}
@@ -931,6 +1042,14 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const
return mImplementation->isValidNativeWindow(window);
}
+Error Display::validateClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs)
+{
+ return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs);
+}
+
bool Display::isValidDisplay(const egl::Display *display)
{
const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap();
@@ -969,7 +1088,7 @@ bool Display::isValidNativeDisplay(EGLNativeDisplayType display)
{
return true;
}
- return (WindowFromDC(display) != NULL);
+ return (WindowFromDC(display) != nullptr);
#else
return true;
#endif
@@ -1000,4 +1119,105 @@ Device *Display::getDevice() const
return mDevice;
}
+gl::Version Display::getMaxSupportedESVersion() const
+{
+ return mImplementation->getMaxSupportedESVersion();
}
+
+EGLint Display::programCacheGetAttrib(EGLenum attrib) const
+{
+ switch (attrib)
+ {
+ case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
+ return static_cast<EGLint>(gl::kProgramHashLength);
+
+ case EGL_PROGRAM_CACHE_SIZE_ANGLE:
+ return static_cast<EGLint>(mMemoryProgramCache.entryCount());
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+Error Display::programCacheQuery(EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize)
+{
+ ASSERT(index >= 0 && index < static_cast<EGLint>(mMemoryProgramCache.entryCount()));
+
+ const angle::MemoryBuffer *programBinary = nullptr;
+ gl::ProgramHash programHash;
+ // TODO(jmadill): Make this thread-safe.
+ bool result =
+ mMemoryProgramCache.getAt(static_cast<size_t>(index), &programHash, &programBinary);
+ if (!result)
+ {
+ return EglBadAccess() << "Program binary not accessible.";
+ }
+
+ ASSERT(keysize && binarysize);
+
+ if (key)
+ {
+ ASSERT(*keysize == static_cast<EGLint>(gl::kProgramHashLength));
+ memcpy(key, programHash.data(), gl::kProgramHashLength);
+ }
+
+ if (binary)
+ {
+ // Note: we check the size here instead of in the validation code, since we need to
+ // access the cache as atomically as possible. It's possible that the cache contents
+ // could change between the validation size check and the retrieval.
+ if (programBinary->size() > static_cast<size_t>(*binarysize))
+ {
+ return EglBadAccess() << "Program binary too large or changed during access.";
+ }
+
+ memcpy(binary, programBinary->data(), programBinary->size());
+ }
+
+ *binarysize = static_cast<EGLint>(programBinary->size());
+ *keysize = static_cast<EGLint>(gl::kProgramHashLength);
+
+ return NoError();
+}
+
+Error Display::programCachePopulate(const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+ ASSERT(keysize == static_cast<EGLint>(gl::kProgramHashLength));
+
+ gl::ProgramHash programHash;
+ memcpy(programHash.data(), key, gl::kProgramHashLength);
+
+ mMemoryProgramCache.putBinary(programHash, reinterpret_cast<const uint8_t *>(binary),
+ static_cast<size_t>(binarysize));
+ return NoError();
+}
+
+EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
+{
+ switch (mode)
+ {
+ case EGL_PROGRAM_CACHE_RESIZE_ANGLE:
+ {
+ size_t initialSize = mMemoryProgramCache.size();
+ mMemoryProgramCache.resize(static_cast<size_t>(limit));
+ return static_cast<EGLint>(initialSize);
+ }
+
+ case EGL_PROGRAM_CACHE_TRIM_ANGLE:
+ return static_cast<EGLint>(mMemoryProgramCache.trim(static_cast<size_t>(limit)));
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+} // namespace egl
diff --git a/src/3rdparty/angle/src/libANGLE/Display.h b/src/3rdparty/angle/src/libANGLE/Display.h
index f80e308347..aa1d1c3b37 100644
--- a/src/3rdparty/angle/src/libANGLE/Display.h
+++ b/src/3rdparty/angle/src/libANGLE/Display.h
@@ -14,15 +14,18 @@
#include <set>
#include <vector>
-#include "libANGLE/Error.h"
+#include "libANGLE/AttributeMap.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Config.h"
-#include "libANGLE/AttributeMap.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/LoggingAnnotator.h"
+#include "libANGLE/MemoryProgramCache.h"
+#include "libANGLE/Version.h"
namespace gl
{
class Context;
+class TextureManager;
}
namespace rx
@@ -35,6 +38,21 @@ namespace egl
class Device;
class Image;
class Surface;
+class Stream;
+class Thread;
+
+using SurfaceSet = std::set<Surface *>;
+
+struct DisplayState final : private angle::NonCopyable
+{
+ DisplayState();
+ ~DisplayState();
+
+ SurfaceSet surfaceSet;
+};
+
+// Constant coded here as a sanity limit.
+constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
class Display final : angle::NonCopyable
{
@@ -42,48 +60,68 @@ class Display final : angle::NonCopyable
~Display();
Error initialize();
- void terminate();
+ Error terminate();
- static egl::Display *GetDisplayFromDevice(void *native_display);
- static egl::Display *GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap);
+ static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
+ static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
+ const AttributeMap &attribMap);
- static const ClientExtensions &getClientExtensions();
- static const std::string &getClientExtensionString();
+ static const ClientExtensions &GetClientExtensions();
+ static const std::string &GetClientExtensionString();
- std::vector<const Config*> getConfigs(const egl::AttributeMap &attribs) const;
- bool getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value);
+ std::vector<const Config *> getConfigs(const AttributeMap &attribs) const;
- Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
+ Error createWindowSurface(const Config *configuration,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
Surface **outSurface);
- Error createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface);
- Error createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs,
+ Error createPbufferSurface(const Config *configuration,
+ const AttributeMap &attribs,
+ Surface **outSurface);
+ Error createPbufferFromClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
Surface **outSurface);
- Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
+ Error createPixmapSurface(const Config *configuration,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
Surface **outSurface);
- Error createImage(gl::Context *context,
+ Error createImage(const gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const AttributeMap &attribs,
Image **outImage);
- Error createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs,
+ Error createStream(const AttributeMap &attribs, Stream **outStream);
+
+ Error createContext(const Config *configuration,
+ gl::Context *shareContext,
+ const AttributeMap &attribs,
gl::Context **outContext);
- Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context);
+ Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context);
- void destroySurface(egl::Surface *surface);
- void destroyImage(egl::Image *image);
- void destroyContext(gl::Context *context);
+ Error destroySurface(Surface *surface);
+ void destroyImage(Image *image);
+ void destroyStream(Stream *stream);
+ Error destroyContext(gl::Context *context);
bool isInitialized() const;
bool isValidConfig(const Config *config) const;
- bool isValidContext(gl::Context *context) const;
- bool isValidSurface(egl::Surface *surface) const;
+ bool isValidContext(const gl::Context *context) const;
+ bool isValidSurface(const Surface *surface) const;
bool isValidImage(const Image *image) const;
+ bool isValidStream(const Stream *stream) const;
bool isValidNativeWindow(EGLNativeWindowType window) const;
- static bool isValidDisplay(const egl::Display *display);
+ Error validateClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs);
+
+ static bool isValidDisplay(const Display *display);
static bool isValidNativeDisplay(EGLNativeDisplayType display);
static bool hasExistingWindowSurface(EGLNativeWindowType window);
@@ -91,8 +129,8 @@ class Display final : angle::NonCopyable
bool testDeviceLost();
void notifyDeviceLost();
- Error waitClient() const;
- Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const;
+ Error waitClient(const gl::Context *context) const;
+ Error waitNative(const gl::Context *context, EGLint engine) const;
const Caps &getCaps() const;
@@ -100,13 +138,31 @@ class Display final : angle::NonCopyable
const std::string &getExtensionString() const;
const std::string &getVendorString() const;
+ EGLint programCacheGetAttrib(EGLenum attrib) const;
+ Error programCacheQuery(EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize);
+ Error programCachePopulate(const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize);
+ EGLint programCacheResize(EGLint limit, EGLenum mode);
+
const AttributeMap &getAttributeMap() const { return mAttributeMap; }
EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; }
- rx::DisplayImpl *getImplementation() { return mImplementation; }
+ rx::DisplayImpl *getImplementation() const { return mImplementation; }
Device *getDevice() const;
EGLenum getPlatform() const { return mPlatform; }
+ gl::Version getMaxSupportedESVersion() const;
+
+ const DisplayState &getState() const { return mState; }
+
+ gl::Context *getProxyContext() const { return mProxyContext.get(); }
+
private:
Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
@@ -117,6 +173,7 @@ class Display final : angle::NonCopyable
void initDisplayExtensions();
void initVendorString();
+ DisplayState mState;
rx::DisplayImpl *mImplementation;
EGLNativeDisplayType mDisplayId;
@@ -130,7 +187,11 @@ class Display final : angle::NonCopyable
typedef std::set<Image *> ImageSet;
ImageSet mImageSet;
+ typedef std::set<Stream *> StreamSet;
+ StreamSet mStreamSet;
+
bool mInitialized;
+ bool mDeviceLost;
Caps mCaps;
@@ -141,8 +202,17 @@ class Display final : angle::NonCopyable
Device *mDevice;
EGLenum mPlatform;
+ angle::LoggingAnnotator mAnnotator;
+
+ gl::TextureManager *mTextureManager;
+ gl::MemoryProgramCache mMemoryProgramCache;
+ size_t mGlobalTextureShareGroupUsers;
+
+ // This gl::Context is a simple proxy to the Display for the GL back-end entry points
+ // that need access to implementation-specific data, like a Renderer object.
+ angle::UniqueObjectPointer<gl::Context, Display> mProxyContext;
};
-}
+} // namespace egl
#endif // LIBANGLE_DISPLAY_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Error.cpp b/src/3rdparty/angle/src/libANGLE/Error.cpp
index fed1594972..388f0259fa 100644
--- a/src/3rdparty/angle/src/libANGLE/Error.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Error.cpp
@@ -10,35 +10,38 @@
#include "libANGLE/Error.h"
#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
#include <cstdarg>
+namespace
+{
+std::unique_ptr<std::string> EmplaceErrorString(std::string &&message)
+{
+ return message.empty() ? std::unique_ptr<std::string>()
+ : std::unique_ptr<std::string>(new std::string(std::move(message)));
+}
+} // anonymous namespace
+
namespace gl
{
-Error::Error(GLenum errorCode, const char *msg, ...) : mCode(errorCode), mID(errorCode)
+Error::Error(GLenum errorCode, std::string &&message)
+ : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
{
- va_list vararg;
- va_start(vararg, msg);
- createMessageString();
- *mMessage = FormatString(msg, vararg);
- va_end(vararg);
}
-Error::Error(GLenum errorCode, GLuint id, const char *msg, ...) : mCode(errorCode), mID(id)
+Error::Error(GLenum errorCode, GLuint id, std::string &&message)
+ : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message)))
{
- va_list vararg;
- va_start(vararg, msg);
- createMessageString();
- *mMessage = FormatString(msg, vararg);
- va_end(vararg);
}
void Error::createMessageString() const
{
if (!mMessage)
{
- mMessage.reset(new std::string);
+ mMessage.reset(new std::string(GetGenericErrorMessage(mCode)));
}
}
@@ -64,34 +67,32 @@ bool Error::operator!=(const Error &other) const
{
return !(*this == other);
}
+
+std::ostream &operator<<(std::ostream &os, const Error &err)
+{
+ return gl::FmtHexShort(os, err.getCode());
}
+} // namespace gl
+
namespace egl
{
-Error::Error(EGLint errorCode, const char *msg, ...) : mCode(errorCode), mID(0)
+Error::Error(EGLint errorCode, std::string &&message)
+ : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
{
- va_list vararg;
- va_start(vararg, msg);
- createMessageString();
- *mMessage = FormatString(msg, vararg);
- va_end(vararg);
}
-Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) : mCode(errorCode), mID(id)
+Error::Error(EGLint errorCode, EGLint id, std::string &&message)
+ : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message)))
{
- va_list vararg;
- va_start(vararg, msg);
- createMessageString();
- *mMessage = FormatString(msg, vararg);
- va_end(vararg);
}
void Error::createMessageString() const
{
if (!mMessage)
{
- mMessage.reset(new std::string);
+ mMessage.reset(new std::string(GetGenericErrorMessage(mCode)));
}
}
@@ -101,4 +102,9 @@ const std::string &Error::getMessage() const
return *mMessage;
}
+std::ostream &operator<<(std::ostream &os, const Error &err)
+{
+ return gl::FmtHexShort(os, err.getCode());
}
+
+} // namespace egl
diff --git a/src/3rdparty/angle/src/libANGLE/Error.h b/src/3rdparty/angle/src/libANGLE/Error.h
index a5f760956a..1d57bb8707 100644
--- a/src/3rdparty/angle/src/libANGLE/Error.h
+++ b/src/3rdparty/angle/src/libANGLE/Error.h
@@ -9,23 +9,89 @@
#ifndef LIBANGLE_ERROR_H_
#define LIBANGLE_ERROR_H_
-#include "angle_gl.h"
#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "common/debug.h"
-#include <string>
#include <memory>
+#include <ostream>
+#include <string>
+
+namespace angle
+{
+template <typename ErrorT, typename ResultT, typename ErrorBaseT, ErrorBaseT NoErrorVal>
+class ANGLE_NO_DISCARD ErrorOrResultBase
+{
+ public:
+ ErrorOrResultBase(const ErrorT &error) : mError(error) {}
+ ErrorOrResultBase(ErrorT &&error) : mError(std::move(error)) {}
+
+ ErrorOrResultBase(ResultT &&result) : mError(NoErrorVal), mResult(std::forward<ResultT>(result))
+ {
+ }
+
+ ErrorOrResultBase(const ResultT &result) : mError(NoErrorVal), mResult(result) {}
+
+ bool isError() const { return mError.isError(); }
+ const ErrorT &getError() const { return mError; }
+ ResultT &&getResult() { return std::move(mResult); }
+
+ private:
+ ErrorT mError;
+ ResultT mResult;
+};
+
+template <typename ErrorT, typename ErrorBaseT, ErrorBaseT NoErrorVal, typename CodeT, CodeT EnumT>
+class ErrorStreamBase : angle::NonCopyable
+{
+ public:
+ ErrorStreamBase() : mID(EnumT) {}
+ ErrorStreamBase(GLuint id) : mID(id) {}
+
+ template <typename T>
+ ErrorStreamBase &operator<<(T value)
+ {
+ mErrorStream << value;
+ return *this;
+ }
+
+ operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); }
+
+ template <typename ResultT>
+ operator ErrorOrResultBase<ErrorT, ResultT, ErrorBaseT, NoErrorVal>()
+ {
+ return static_cast<ErrorT>(*this);
+ }
+
+ private:
+ GLuint mID;
+ std::ostringstream mErrorStream;
+};
+} // namespace angle
+
+namespace egl
+{
+class Error;
+} // namespace egl
namespace gl
{
-class Error final
+class ANGLE_NO_DISCARD Error final
{
public:
explicit inline Error(GLenum errorCode);
- Error(GLenum errorCode, const char *msg, ...);
- Error(GLenum errorCode, GLuint id, const char *msg, ...);
+ Error(GLenum errorCode, std::string &&message);
+ Error(GLenum errorCode, GLuint id, std::string &&message);
inline Error(const Error &other);
inline Error(Error &&other);
+ inline ~Error() = default;
+
+ // automatic error type conversion
+ inline Error(egl::Error &&eglErr);
+ inline Error(egl::Error eglErr);
inline Error &operator=(const Error &other);
inline Error &operator=(Error &&other);
@@ -43,40 +109,60 @@ class Error final
private:
void createMessageString() const;
+ friend std::ostream &operator<<(std::ostream &os, const Error &err);
+ friend class egl::Error;
+
GLenum mCode;
GLuint mID;
mutable std::unique_ptr<std::string> mMessage;
};
-template <typename T>
-class ErrorOrResult
+template <typename ResultT>
+using ErrorOrResult = angle::ErrorOrResultBase<Error, ResultT, GLenum, GL_NO_ERROR>;
+
+namespace priv
{
- public:
- ErrorOrResult(const gl::Error &error) : mError(error) {}
- ErrorOrResult(T &&result) : mError(GL_NO_ERROR), mResult(std::move(result)) {}
- bool isError() const { return mError.isError(); }
- const gl::Error &getError() const { return mError; }
- T &&getResult() { return std::move(mResult); }
+template <GLenum EnumT>
+using ErrorStream = angle::ErrorStreamBase<Error, GLenum, GL_NO_ERROR, GLenum, EnumT>;
- private:
- Error mError;
- T mResult;
-};
+} // namespace priv
+
+using InternalError = priv::ErrorStream<GL_INVALID_OPERATION>;
+
+using InvalidEnum = priv::ErrorStream<GL_INVALID_ENUM>;
+using InvalidValue = priv::ErrorStream<GL_INVALID_VALUE>;
+using InvalidOperation = priv::ErrorStream<GL_INVALID_OPERATION>;
+using StackOverflow = priv::ErrorStream<GL_STACK_OVERFLOW>;
+using StackUnderflow = priv::ErrorStream<GL_STACK_UNDERFLOW>;
+using OutOfMemory = priv::ErrorStream<GL_OUT_OF_MEMORY>;
+using InvalidFramebufferOperation = priv::ErrorStream<GL_INVALID_FRAMEBUFFER_OPERATION>;
+
+inline Error NoError()
+{
+ return Error(GL_NO_ERROR);
+}
+
+using LinkResult = ErrorOrResult<bool>;
} // namespace gl
namespace egl
{
-class Error final
+class ANGLE_NO_DISCARD Error final
{
public:
explicit inline Error(EGLint errorCode);
- Error(EGLint errorCode, const char *msg, ...);
- Error(EGLint errorCode, EGLint id, const char *msg, ...);
+ Error(EGLint errorCode, std::string &&message);
+ Error(EGLint errorCode, EGLint id, std::string &&message);
inline Error(const Error &other);
inline Error(Error &&other);
+ inline ~Error() = default;
+
+ // automatic error type conversion
+ inline Error(gl::Error &&glErr);
+ inline Error(gl::Error glErr);
inline Error &operator=(const Error &other);
inline Error &operator=(Error &&other);
@@ -90,13 +176,92 @@ class Error final
private:
void createMessageString() const;
+ friend std::ostream &operator<<(std::ostream &os, const Error &err);
+ friend class gl::Error;
+
EGLint mCode;
EGLint mID;
mutable std::unique_ptr<std::string> mMessage;
};
+template <typename ResultT>
+using ErrorOrResult = angle::ErrorOrResultBase<Error, ResultT, EGLint, EGL_SUCCESS>;
+
+namespace priv
+{
+
+template <EGLint EnumT>
+using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, EnumT>;
+
+} // namespace priv
+
+using EglNotInitialized = priv::ErrorStream<EGL_NOT_INITIALIZED>;
+using EglBadAccess = priv::ErrorStream<EGL_BAD_ACCESS>;
+using EglBadAlloc = priv::ErrorStream<EGL_BAD_ALLOC>;
+using EglBadAttribute = priv::ErrorStream<EGL_BAD_ATTRIBUTE>;
+using EglBadConfig = priv::ErrorStream<EGL_BAD_CONFIG>;
+using EglBadContext = priv::ErrorStream<EGL_BAD_CONTEXT>;
+using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>;
+using EglBadDisplay = priv::ErrorStream<EGL_BAD_DISPLAY>;
+using EglBadMatch = priv::ErrorStream<EGL_BAD_MATCH>;
+using EglBadNativeWindow = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>;
+using EglBadParameter = priv::ErrorStream<EGL_BAD_PARAMETER>;
+using EglBadSurface = priv::ErrorStream<EGL_BAD_SURFACE>;
+using EglContextLost = priv::ErrorStream<EGL_CONTEXT_LOST>;
+using EglBadStream = priv::ErrorStream<EGL_BAD_STREAM_KHR>;
+using EglBadState = priv::ErrorStream<EGL_BAD_STATE_KHR>;
+using EglBadDevice = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
+
+inline Error NoError()
+{
+ return Error(EGL_SUCCESS);
+}
+
} // namespace egl
+#define ANGLE_CONCAT1(x, y) x##y
+#define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y)
+#define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__)
+
+#define ANGLE_TRY_TEMPLATE(EXPR, FUNC) \
+ { \
+ auto ANGLE_LOCAL_VAR = EXPR; \
+ if (ANGLE_LOCAL_VAR.isError()) \
+ { \
+ FUNC(ANGLE_LOCAL_VAR); \
+ } \
+ } \
+ ANGLE_EMPTY_STATEMENT
+
+#define ANGLE_RETURN(X) return X;
+#define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN);
+
+#define ANGLE_TRY_RESULT(EXPR, RESULT) \
+ { \
+ auto ANGLE_LOCAL_VAR = EXPR; \
+ if (ANGLE_LOCAL_VAR.isError()) \
+ { \
+ return ANGLE_LOCAL_VAR.getError(); \
+ } \
+ RESULT = ANGLE_LOCAL_VAR.getResult(); \
+ } \
+ ANGLE_EMPTY_STATEMENT
+
+// TODO(jmadill): Introduce way to store errors to a const Context.
+#define ANGLE_SWALLOW_ERR(EXPR) \
+ { \
+ auto ANGLE_LOCAL_VAR = EXPR; \
+ if (ANGLE_LOCAL_VAR.isError()) \
+ { \
+ ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \
+ } \
+ } \
+ ANGLE_EMPTY_STATEMENT
+
+#undef ANGLE_LOCAL_VAR
+#undef ANGLE_CONCAT2
+#undef ANGLE_CONCAT1
+
#include "Error.inl"
#endif // LIBANGLE_ERROR_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Error.inl b/src/3rdparty/angle/src/libANGLE/Error.inl
index 900fc5fd03..4632830ce0 100644
--- a/src/3rdparty/angle/src/libANGLE/Error.inl
+++ b/src/3rdparty/angle/src/libANGLE/Error.inl
@@ -37,6 +37,21 @@ Error::Error(Error &&other)
{
}
+// automatic error type conversion
+Error::Error(egl::Error &&eglErr)
+ : mCode(GL_INVALID_OPERATION),
+ mID(0),
+ mMessage(std::move(eglErr.mMessage))
+{
+}
+
+Error::Error(egl::Error eglErr)
+ : mCode(GL_INVALID_OPERATION),
+ mID(0),
+ mMessage(std::move(eglErr.mMessage))
+{
+}
+
Error &Error::operator=(const Error &other)
{
mCode = other.mCode;
@@ -82,7 +97,7 @@ bool Error::isError() const
return (mCode != GL_NO_ERROR);
}
-}
+} // namespace gl
namespace egl
{
@@ -111,6 +126,21 @@ Error::Error(Error &&other)
{
}
+// automatic error type conversion
+Error::Error(gl::Error &&glErr)
+ : mCode(EGL_BAD_ACCESS),
+ mID(0),
+ mMessage(std::move(glErr.mMessage))
+{
+}
+
+Error::Error(gl::Error glErr)
+ : mCode(EGL_BAD_ACCESS),
+ mID(0),
+ mMessage(std::move(glErr.mMessage))
+{
+}
+
Error &Error::operator=(const Error &other)
{
mCode = other.mCode;
diff --git a/src/3rdparty/angle/src/libANGLE/ErrorStrings.h b/src/3rdparty/angle/src/libANGLE/ErrorStrings.h
new file mode 100644
index 0000000000..93d64482d9
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/ErrorStrings.h
@@ -0,0 +1,173 @@
+//
+// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ErrorStrings.h: Contains mapping of commonly used error messages
+
+#ifndef LIBANGLE_ERRORSTRINGS_H_
+#define LIBANGLE_ERRORSTRINGS_H_
+
+#define ERRMSG(name, message) \
+ static const constexpr char *kError##name = static_cast<const char *>(message);
+#define ANGLE_VALIDATION_ERR(context, error, errorName) \
+ context->handleError(error << kError##errorName)
+
+namespace gl
+{
+ERRMSG(BufferNotBound, "A buffer must be bound.");
+ERRMSG(CompressedTextureDimensionsMustMatchData,
+ "Compressed texture dimensions must exactly match the dimensions of the data passed in.");
+ERRMSG(CompressedTexturesNotAttachable, "Compressed textures cannot be attached to a framebuffer.");
+ERRMSG(CubemapFacesEqualDimensions, "Each cubemap face must have equal width and height.");
+ERRMSG(CubemapIncomplete,
+ "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size.");
+ERRMSG(DefaultFramebufferInvalidAttachment,
+ "Invalid attachment when the default framebuffer is bound.");
+ERRMSG(DefaultFramebufferTarget, "It is invalid to change default FBO's attachments");
+ERRMSG(EnumNotSupported, "Enum is not currently supported.");
+ERRMSG(EnumRequiresGLES31, "Enum requires GLES 3.1");
+ERRMSG(ES31Required, "OpenGL ES 3.1 Required");
+ERRMSG(ES3Required, "OpenGL ES 3.0 Required.");
+ERRMSG(ExceedsMaxElement, "Element value exceeds maximum element index.");
+ERRMSG(ExpectedProgramName, "Expected a program name, but found a shader name.");
+ERRMSG(ExpectedShaderName, "Expected a shader name, but found a program name.");
+ERRMSG(ExtensionNotEnabled, "Extension is not enabled.");
+ERRMSG(FeedbackLoop, "Feedback loop formed between Framebuffer and active Texture.");
+ERRMSG(FramebufferIncompleteAttachment,
+ "Attachment type must be compatible with attachment object.");
+ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
+ERRMSG(IndexExceedsMaxActiveUniform, "Index e