summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-20 15:06:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-22 11:48:58 +0000
commitdaa093eea7c773db06799a13bd7e4e2e2a9f8f14 (patch)
tree96cc5e7b9194c1b29eab927730bfa419e7111c25 /chromium/gpu/command_buffer
parentbe59a35641616a4cf23c4a13fa0632624b021c1b (diff)
downloadqtwebengine-chromium-daa093eea7c773db06799a13bd7e4e2e2a9f8f14.tar.gz
BASELINE: Update Chromium to 63.0.3239.58
Change-Id: Ia93b322a00ba4dd4004f3bcf1254063ba90e1605 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/gpu/command_buffer')
-rw-r--r--chromium/gpu/command_buffer/OWNERS1
-rwxr-xr-xchromium/gpu/command_buffer/build_gles2_cmd_buffer.py1
-rw-r--r--chromium/gpu/command_buffer/client/client_discardable_manager.h4
-rw-r--r--chromium/gpu/command_buffer/client/client_test_helper.h3
-rw-r--r--chromium/gpu/command_buffer/client/gles2_implementation.h6
-rw-r--r--chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc52
-rw-r--r--chromium/gpu/command_buffer/client/gpu_control.h2
-rw-r--r--chromium/gpu/command_buffer/client/query_tracker.cc5
-rw-r--r--chromium/gpu/command_buffer/client/query_tracker.h4
-rw-r--r--chromium/gpu/command_buffer/client/ring_buffer.h7
-rw-r--r--chromium/gpu/command_buffer/client/share_group.cc5
-rw-r--r--chromium/gpu/command_buffer/client/shared_memory_limits.h2
-rw-r--r--chromium/gpu/command_buffer/common/capabilities.h12
-rw-r--r--chromium/gpu/command_buffer/common/debug_marker_manager.h5
-rw-r--r--chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h1
-rw-r--r--chromium/gpu/command_buffer/common/scheduling_priority.cc4
-rw-r--r--chromium/gpu/command_buffer/common/scheduling_priority.h15
-rw-r--r--chromium/gpu/command_buffer/service/client_service_map.h23
-rw-r--r--chromium/gpu/command_buffer/service/context_group.cc32
-rw-r--r--chromium/gpu/command_buffer/service/context_group_unittest.cc7
-rw-r--r--chromium/gpu/command_buffer/service/create_gr_gl_interface.cc20
-rw-r--r--chromium/gpu/command_buffer/service/feature_info.cc88
-rw-r--r--chromium/gpu/command_buffer/service/feature_info.h3
-rw-r--r--chromium/gpu/command_buffer/service/framebuffer_manager.cc17
-rw-r--r--chromium/gpu/command_buffer/service/framebuffer_manager.h6
-rw-r--r--chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc4
-rw-r--r--chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc4
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc61
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder.h15
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc5
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h3
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc711
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h157
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h14
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc357
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc1020
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_drawing.cc41
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_framebuffers.cc420
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc108
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h64
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc6
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h1
-rw-r--r--chromium/gpu/command_buffer/service/gpu_preferences.h3
-rw-r--r--chromium/gpu/command_buffer/service/gpu_switches.cc4
-rw-r--r--chromium/gpu/command_buffer/service/gpu_switches.h1
-rw-r--r--chromium/gpu/command_buffer/service/gpu_tracer.cc47
-rw-r--r--chromium/gpu/command_buffer/service/gpu_tracer.h52
-rw-r--r--chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc111
-rw-r--r--chromium/gpu/command_buffer/service/mailbox_manager_sync.cc6
-rw-r--r--chromium/gpu/command_buffer/service/query_manager.h10
-rw-r--r--chromium/gpu/command_buffer/service/query_manager_unittest.cc5
-rw-r--r--chromium/gpu/command_buffer/service/sampler_manager.cc2
-rw-r--r--chromium/gpu/command_buffer/service/scheduler.cc52
-rw-r--r--chromium/gpu/command_buffer/service/scheduler.h12
-rw-r--r--chromium/gpu/command_buffer/service/scheduler_unittest.cc78
-rw-r--r--chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc4
-rw-r--r--chromium/gpu/command_buffer/service/service_utils.cc7
-rw-r--r--chromium/gpu/command_buffer/service/service_utils.h5
-rw-r--r--chromium/gpu/command_buffer/service/shader_translator.cc8
-rw-r--r--chromium/gpu/command_buffer/service/shader_translator_unittest.cc14
-rw-r--r--chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc4
-rw-r--r--chromium/gpu/command_buffer/service/test_helper.cc24
-rw-r--r--chromium/gpu/command_buffer/service/texture_manager.cc5
-rw-r--r--chromium/gpu/command_buffer/service/texture_manager_unittest.cc10
64 files changed, 2798 insertions, 982 deletions
diff --git a/chromium/gpu/command_buffer/OWNERS b/chromium/gpu/command_buffer/OWNERS
index 49a178a25da..95fbe52bc30 100644
--- a/chromium/gpu/command_buffer/OWNERS
+++ b/chromium/gpu/command_buffer/OWNERS
@@ -1,5 +1,4 @@
piman@chromium.org
-jbauman@chromium.org
bajones@chromium.org
zmo@chromium.org
vmiura@chromium.org
diff --git a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py
index c11416239e4..6c90e56f5b3 100755
--- a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2057,6 +2057,7 @@ _NAMED_TYPE_INFO = {
'GL_RGB_YCRCB_420_CHROMIUM',
'GL_RGB_YCBCR_422_CHROMIUM',
'GL_RGB_YCBCR_420V_CHROMIUM',
+ 'GL_R16_EXT',
],
},
'TextureInternalFormatStorage': {
diff --git a/chromium/gpu/command_buffer/client/client_discardable_manager.h b/chromium/gpu/command_buffer/client/client_discardable_manager.h
index 780b80dcf17..25418eb40d4 100644
--- a/chromium/gpu/command_buffer/client/client_discardable_manager.h
+++ b/chromium/gpu/command_buffer/client/client_discardable_manager.h
@@ -6,9 +6,9 @@
#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_
#include <map>
-#include <queue>
#include <set>
+#include "base/containers/queue.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/discardable_handle.h"
#include "gpu/gpu_export.h"
@@ -62,7 +62,7 @@ class GPU_EXPORT ClientDiscardableManager {
// Handles that are pending service deletion, and can be re-used once
// ClientDiscardableHandle::CanBeReUsed returns true.
- std::queue<ClientDiscardableHandle> pending_handles_;
+ base::queue<ClientDiscardableHandle> pending_handles_;
DISALLOW_COPY_AND_ASSIGN(ClientDiscardableManager);
};
diff --git a/chromium/gpu/command_buffer/client/client_test_helper.h b/chromium/gpu/command_buffer/client/client_test_helper.h
index 25a05ada70c..71bd3c26bf9 100644
--- a/chromium/gpu/command_buffer/client/client_test_helper.h
+++ b/chromium/gpu/command_buffer/client/client_test_helper.h
@@ -103,7 +103,7 @@ class MockClientGpuControl : public GpuControl {
virtual ~MockClientGpuControl();
MOCK_METHOD1(SetGpuControlClient, void(GpuControlClient*));
- MOCK_METHOD0(GetCapabilities, Capabilities());
+ MOCK_CONST_METHOD0(GetCapabilities, const Capabilities&());
MOCK_METHOD4(CreateImage,
int32_t(ClientBuffer buffer,
size_t width,
@@ -136,4 +136,3 @@ class MockClientGpuControl : public GpuControl {
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_
-
diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.h b/chromium/gpu/command_buffer/client/gles2_implementation.h
index 17f77992128..8ce0179fbef 100644
--- a/chromium/gpu/command_buffer/client/gles2_implementation.h
+++ b/chromium/gpu/command_buffer/client/gles2_implementation.h
@@ -11,13 +11,13 @@
#include <list>
#include <map>
#include <memory>
-#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/trace_event/memory_dump_provider.h"
@@ -693,8 +693,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation
DebugMarkerManager debug_marker_manager_;
std::string this_in_hex_;
- std::queue<int32_t> swap_buffers_tokens_;
- std::queue<int32_t> rate_limit_tokens_;
+ base::queue<int32_t> swap_buffers_tokens_;
+ base::queue<int32_t> rate_limit_tokens_;
ExtensionStatus chromium_framebuffer_multisample_;
diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 386ff6afb4f..d724023c4e5 100644
--- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -46,6 +46,7 @@ using testing::Sequence;
using testing::StrictMock;
using testing::Truly;
using testing::Return;
+using testing::ReturnRef;
namespace gpu {
namespace gles2 {
@@ -445,42 +446,42 @@ class GLES2ImplementationTest : public testing::Test {
helper_->Initialize(limits.command_buffer_size);
gpu_control_.reset(new StrictMock<MockClientGpuControl>());
- Capabilities capabilities;
- capabilities.VisitPrecisions(
+ capabilities_.VisitPrecisions(
[](GLenum shader, GLenum type,
Capabilities::ShaderPrecision* precision) {
precision->min_range = 3;
precision->max_range = 5;
precision->precision = 7;
});
- capabilities.max_combined_texture_image_units =
+ capabilities_.max_combined_texture_image_units =
kMaxCombinedTextureImageUnits;
- capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
- capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
- capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
- capabilities.max_texture_image_units = kMaxTextureImageUnits;
- capabilities.max_texture_size = kMaxTextureSize;
- capabilities.max_varying_vectors = kMaxVaryingVectors;
- capabilities.max_vertex_attribs = kMaxVertexAttribs;
- capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
- capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
- capabilities.max_viewport_width = kMaxViewportWidth;
- capabilities.max_viewport_height = kMaxViewportHeight;
- capabilities.num_compressed_texture_formats =
+ capabilities_.max_cube_map_texture_size = kMaxCubeMapTextureSize;
+ capabilities_.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
+ capabilities_.max_renderbuffer_size = kMaxRenderbufferSize;
+ capabilities_.max_texture_image_units = kMaxTextureImageUnits;
+ capabilities_.max_texture_size = kMaxTextureSize;
+ capabilities_.max_varying_vectors = kMaxVaryingVectors;
+ capabilities_.max_vertex_attribs = kMaxVertexAttribs;
+ capabilities_.max_vertex_texture_image_units =
+ kMaxVertexTextureImageUnits;
+ capabilities_.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
+ capabilities_.max_viewport_width = kMaxViewportWidth;
+ capabilities_.max_viewport_height = kMaxViewportHeight;
+ capabilities_.num_compressed_texture_formats =
kNumCompressedTextureFormats;
- capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
- capabilities.max_transform_feedback_separate_attribs =
+ capabilities_.num_shader_binary_formats = kNumShaderBinaryFormats;
+ capabilities_.max_transform_feedback_separate_attribs =
kMaxTransformFeedbackSeparateAttribs;
- capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
- capabilities.bind_generates_resource_chromium =
+ capabilities_.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
+ capabilities_.bind_generates_resource_chromium =
bind_generates_resource_service ? 1 : 0;
- capabilities.sync_query = sync_query;
- capabilities.occlusion_query_boolean = occlusion_query_boolean;
- capabilities.timer_queries = timer_queries;
- capabilities.major_version = major_version;
- capabilities.minor_version = minor_version;
+ capabilities_.sync_query = sync_query;
+ capabilities_.occlusion_query_boolean = occlusion_query_boolean;
+ capabilities_.timer_queries = timer_queries;
+ capabilities_.major_version = major_version;
+ capabilities_.minor_version = minor_version;
EXPECT_CALL(*gpu_control_, GetCapabilities())
- .WillOnce(Return(capabilities));
+ .WillOnce(ReturnRef(capabilities_));
{
InSequence sequence;
@@ -543,6 +544,7 @@ class GLES2ImplementationTest : public testing::Test {
std::unique_ptr<GLES2Implementation> gl_;
CommandBufferEntry* commands_;
int token_;
+ Capabilities capabilities_;
};
GLES2ImplementationTest() : commands_(NULL) {}
diff --git a/chromium/gpu/command_buffer/client/gpu_control.h b/chromium/gpu/command_buffer/client/gpu_control.h
index 7c6384bd4ea..948788485bf 100644
--- a/chromium/gpu/command_buffer/client/gpu_control.h
+++ b/chromium/gpu/command_buffer/client/gpu_control.h
@@ -40,7 +40,7 @@ class GPU_EXPORT GpuControl {
virtual void SetGpuControlClient(GpuControlClient* gpu_control_client) = 0;
- virtual Capabilities GetCapabilities() = 0;
+ virtual const Capabilities& GetCapabilities() const = 0;
// Create an image for a client buffer with the given dimensions and
// format. Returns its ID or -1 on error.
diff --git a/chromium/gpu/command_buffer/client/query_tracker.cc b/chromium/gpu/command_buffer/client/query_tracker.cc
index a4b76f5f0b3..0def9cda03b 100644
--- a/chromium/gpu/command_buffer/client/query_tracker.cc
+++ b/chromium/gpu/command_buffer/client/query_tracker.cc
@@ -13,6 +13,7 @@
#include <stdint.h>
#include "base/atomicops.h"
+#include "base/containers/circular_deque.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
@@ -111,8 +112,7 @@ void QuerySyncManager::Free(const QuerySyncManager::QueryInfo& info) {
}
void QuerySyncManager::Shrink(CommandBufferHelper* helper) {
- std::deque<std::unique_ptr<Bucket>> new_buckets;
- bool has_token = false;
+ base::circular_deque<std::unique_ptr<Bucket>> new_buckets;
uint32_t token = 0;
while (!buckets_.empty()) {
std::unique_ptr<Bucket>& bucket = buckets_.front();
@@ -124,7 +124,6 @@ void QuerySyncManager::Shrink(CommandBufferHelper* helper) {
// access the shared memory after current commands, so we can
// free-pending-token.
token = helper->InsertToken();
- has_token = true;
mapped_memory_->FreePendingToken(bucket->syncs, token);
} else {
new_buckets.push_back(std::move(bucket));
diff --git a/chromium/gpu/command_buffer/client/query_tracker.h b/chromium/gpu/command_buffer/client/query_tracker.h
index a52910055d2..7d104ac0228 100644
--- a/chromium/gpu/command_buffer/client/query_tracker.h
+++ b/chromium/gpu/command_buffer/client/query_tracker.h
@@ -11,11 +11,11 @@
#include <stdint.h>
#include <bitset>
-#include <deque>
#include <list>
#include <memory>
#include "base/atomicops.h"
+#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
@@ -78,7 +78,7 @@ class GLES2_IMPL_EXPORT QuerySyncManager {
FRIEND_TEST_ALL_PREFIXES(QuerySyncManagerTest, Shrink);
MappedMemoryManager* mapped_memory_;
- std::deque<std::unique_ptr<Bucket>> buckets_;
+ base::circular_deque<std::unique_ptr<Bucket>> buckets_;
DISALLOW_COPY_AND_ASSIGN(QuerySyncManager);
};
diff --git a/chromium/gpu/command_buffer/client/ring_buffer.h b/chromium/gpu/command_buffer/client/ring_buffer.h
index 48ba789ec9d..f2278229ad2 100644
--- a/chromium/gpu/command_buffer/client/ring_buffer.h
+++ b/chromium/gpu/command_buffer/client/ring_buffer.h
@@ -9,8 +9,7 @@
#include <stdint.h>
-#include <deque>
-
+#include "base/containers/circular_deque.h"
#include "base/logging.h"
#include "base/macros.h"
#include "gpu/gpu_export.h"
@@ -114,8 +113,8 @@ class GPU_EXPORT RingBuffer {
State state;
};
- typedef std::deque<Block> Container;
- typedef unsigned int BlockIndex;
+ using Container = base::circular_deque<Block>;
+ using BlockIndex = unsigned int;
void FreeOldestBlock();
diff --git a/chromium/gpu/command_buffer/client/share_group.cc b/chromium/gpu/command_buffer/client/share_group.cc
index 126332cc865..5c4e4da21e0 100644
--- a/chromium/gpu/command_buffer/client/share_group.cc
+++ b/chromium/gpu/command_buffer/client/share_group.cc
@@ -6,8 +6,9 @@
#include <stdint.h>
-#include <stack>
#include <vector>
+
+#include "base/containers/stack.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
@@ -255,7 +256,7 @@ class StrictIdHandler : public IdHandlerInterface {
base::Lock lock_;
std::vector<uint8_t> id_states_;
- std::stack<uint32_t> free_ids_;
+ base::stack<uint32_t> free_ids_;
};
// An id handler for ids that are never reused.
diff --git a/chromium/gpu/command_buffer/client/shared_memory_limits.h b/chromium/gpu/command_buffer/client/shared_memory_limits.h
index ed62e956cfb..16da712c7e4 100644
--- a/chromium/gpu/command_buffer/client/shared_memory_limits.h
+++ b/chromium/gpu/command_buffer/client/shared_memory_limits.h
@@ -26,7 +26,7 @@ struct SharedMemoryLimits {
: 0;
// On memory constrained devices, switch to lower limits.
- if (base::SysInfo::AmountOfPhysicalMemoryMB() < 512) {
+ if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) {
command_buffer_size = 512 * 1024;
start_transfer_buffer_size = 256 * 1024;
min_transfer_buffer_size = 128 * 1024;
diff --git a/chromium/gpu/command_buffer/common/capabilities.h b/chromium/gpu/command_buffer/common/capabilities.h
index e49f3004ac1..46b02e5d88d 100644
--- a/chromium/gpu/command_buffer/common/capabilities.h
+++ b/chromium/gpu/command_buffer/common/capabilities.h
@@ -152,8 +152,6 @@ struct GPU_EXPORT Capabilities {
bool flips_vertically = false;
bool msaa_is_slow = false;
bool disable_one_component_textures = false;
- bool disable_multisampling_color_mask_usage = false;
- bool disable_webgl_rgb_multisampling_usage = false;
bool gpu_rasterization = false;
bool avoid_stencil_buffers = false;
bool multisample_compatibility = false;
@@ -168,19 +166,13 @@ struct GPU_EXPORT Capabilities {
// details.
bool chromium_image_rgb_emulation = false;
- // When true, RGB framebuffer formats are unsupported. Emulate with RGBA to
- // work around this. See https://crbug.com/449150 for an example.
- bool emulate_rgb_buffer_with_rgba = false;
-
- // When true, is safe to convert a canvas from software to accelerated.
- // See https://crbug.com/710029.
- bool software_to_accelerated_canvas_upgrade = true;
-
// When true, non-empty post sub buffer calls are unsupported.
bool disable_non_empty_post_sub_buffers = false;
bool disable_2d_canvas_copy_on_write = false;
+ bool texture_npot = false;
+
int major_version = 2;
int minor_version = 0;
};
diff --git a/chromium/gpu/command_buffer/common/debug_marker_manager.h b/chromium/gpu/command_buffer/common/debug_marker_manager.h
index 65e0cd011d6..810352cd0c5 100644
--- a/chromium/gpu/command_buffer/common/debug_marker_manager.h
+++ b/chromium/gpu/command_buffer/common/debug_marker_manager.h
@@ -5,8 +5,9 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_DEBUG_MARKER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_DEBUG_MARKER_MANAGER_H_
-#include <stack>
#include <string>
+
+#include "base/containers/stack.h"
#include "gpu/gpu_export.h"
namespace gpu {
@@ -49,7 +50,7 @@ class GPU_EXPORT DebugMarkerManager {
std::string marker_;
};
- typedef std::stack<Group> GroupStack;
+ using GroupStack = base::stack<Group>;
GroupStack group_stack_;
std::string empty_;
diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index b6a91d84d79..1e8f611f43a 100644
--- a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -5622,6 +5622,7 @@ std::string GLES2Util::GetStringTextureSizedTextureFilterableInternalFormat(
{GL_RGB_YCRCB_420_CHROMIUM, "GL_RGB_YCRCB_420_CHROMIUM"},
{GL_RGB_YCBCR_422_CHROMIUM, "GL_RGB_YCBCR_422_CHROMIUM"},
{GL_RGB_YCBCR_420V_CHROMIUM, "GL_RGB_YCBCR_420V_CHROMIUM"},
+ {GL_R16_EXT, "GL_R16_EXT"},
};
return GLES2Util::GetQualifiedEnumString(string_table,
arraysize(string_table), value);
diff --git a/chromium/gpu/command_buffer/common/scheduling_priority.cc b/chromium/gpu/command_buffer/common/scheduling_priority.cc
index 62b6456c921..351a65182da 100644
--- a/chromium/gpu/command_buffer/common/scheduling_priority.cc
+++ b/chromium/gpu/command_buffer/common/scheduling_priority.cc
@@ -10,16 +10,12 @@ namespace gpu {
const char* SchedulingPriorityToString(SchedulingPriority priority) {
switch (priority) {
- case SchedulingPriority::kHighest:
- return "Highest";
case SchedulingPriority::kHigh:
return "High";
case SchedulingPriority::kNormal:
return "Normal";
case SchedulingPriority::kLow:
return "Low";
- case SchedulingPriority::kLowest:
- return "Lowest";
}
NOTREACHED();
return "";
diff --git a/chromium/gpu/command_buffer/common/scheduling_priority.h b/chromium/gpu/command_buffer/common/scheduling_priority.h
index ca93809f608..b4bdfb0c601 100644
--- a/chromium/gpu/command_buffer/common/scheduling_priority.h
+++ b/chromium/gpu/command_buffer/common/scheduling_priority.h
@@ -10,19 +10,16 @@
namespace gpu {
enum class SchedulingPriority {
- // The Highest and High priorities can be used by priveleged clients only.
- // This priority should be used for UI contexts.
- kHighest,
- // This priority is used by the scheduler for prioritizing contexts which have
- // outstanding sync token waits.
+ // The High priority can be used by priveleged clients only. This priority is
+ // used for UI contexts and by the scheduler for prioritizing contexts which
+ // have outstanding sync token waits or client side waits.
kHigh,
// The following priorities can be used on unprivileged clients.
- // This priority should be used as the default priority for all contexts.
+ // This priority is used as the default priority for all contexts.
kNormal,
+ // This priority is used for worker contexts.
kLow,
- // This priority should be used for worker contexts.
- kLowest,
- kLast = kLowest
+ kLast = kLow
};
GPU_EXPORT const char* SchedulingPriorityToString(SchedulingPriority priority);
diff --git a/chromium/gpu/command_buffer/service/client_service_map.h b/chromium/gpu/command_buffer/service/client_service_map.h
index 904a0951716..5d83573525a 100644
--- a/chromium/gpu/command_buffer/service/client_service_map.h
+++ b/chromium/gpu/command_buffer/service/client_service_map.h
@@ -30,18 +30,17 @@ class ClientServiceMap {
void Clear() { client_to_service_.clear(); }
bool GetServiceID(ClientType client_id, ServiceType* service_id) const {
- if (client_id == 0) {
- if (service_id) {
- *service_id = 0;
- }
- return true;
- }
auto iter = client_to_service_.find(client_id);
if (iter != client_to_service_.end()) {
if (service_id) {
*service_id = iter->second;
}
return true;
+ } else if (client_id == 0) {
+ if (service_id) {
+ *service_id = 0;
+ }
+ return true;
}
return false;
}
@@ -55,12 +54,6 @@ class ClientServiceMap {
}
bool GetClientID(ServiceType service_id, ClientType* client_id) const {
- if (service_id == 0) {
- if (client_id) {
- *client_id = 0;
- }
- return true;
- }
for (auto mapping : client_to_service_) {
if (mapping.second == service_id) {
if (client_id) {
@@ -69,6 +62,12 @@ class ClientServiceMap {
return true;
}
}
+ if (service_id == 0) {
+ if (client_id) {
+ *client_id = 0;
+ }
+ return true;
+ }
return false;
}
diff --git a/chromium/gpu/command_buffer/service/context_group.cc b/chromium/gpu/command_buffer/service/context_group.cc
index 11a8eb90e8d..146958140b6 100644
--- a/chromium/gpu/command_buffer/service/context_group.cc
+++ b/chromium/gpu/command_buffer/service/context_group.cc
@@ -46,15 +46,15 @@ DisallowedFeatures AdjustDisallowedFeatures(
DisallowedFeatures adjusted_disallowed_features = disallowed_features;
if (context_type == CONTEXT_TYPE_WEBGL1) {
adjusted_disallowed_features.npot_support = true;
- adjusted_disallowed_features.oes_texture_half_float_linear = true;
}
if (context_type == CONTEXT_TYPE_WEBGL1 ||
context_type == CONTEXT_TYPE_WEBGL2) {
adjusted_disallowed_features.chromium_color_buffer_float_rgba = true;
adjusted_disallowed_features.chromium_color_buffer_float_rgb = true;
adjusted_disallowed_features.ext_color_buffer_float = true;
- adjusted_disallowed_features.ext_color_buffer_half_float = true;
adjusted_disallowed_features.oes_texture_float_linear = true;
+ adjusted_disallowed_features.ext_color_buffer_half_float = true;
+ adjusted_disallowed_features.oes_texture_half_float_linear = true;
}
return adjusted_disallowed_features;
}
@@ -128,12 +128,24 @@ ContextGroup::ContextGroup(
bool ContextGroup::Initialize(GLES2Decoder* decoder,
ContextType context_type,
const DisallowedFeatures& disallowed_features) {
- bool enable_es3 = context_type == CONTEXT_TYPE_OPENGLES3 ||
- context_type == CONTEXT_TYPE_WEBGL2;
- if (!gpu_preferences_.enable_es3_apis && enable_es3) {
- DLOG(ERROR) << "ContextGroup::Initialize failed because ES3 APIs are "
- << "not available.";
- return false;
+ switch (context_type) {
+ case CONTEXT_TYPE_WEBGL1:
+ if (kGpuFeatureStatusBlacklisted ==
+ gpu_feature_info_.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL]) {
+ DLOG(ERROR) << "ContextGroup::Initialize failed: WebGL1 baclklisted";
+ return false;
+ }
+ break;
+ case CONTEXT_TYPE_WEBGL2:
+ if (kGpuFeatureStatusBlacklisted ==
+ gpu_feature_info_
+ .status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL2]) {
+ DLOG(ERROR) << "ContextGroup::Initialize failed: WebGL2 blacklisted";
+ return false;
+ }
+ break;
+ default:
+ break;
}
if (HaveContexts()) {
if (context_type != feature_info_->context_type()) {
@@ -176,7 +188,9 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder,
}
}
- if (enable_es3 || feature_info_->feature_flags().ext_draw_buffers) {
+ if (context_type == CONTEXT_TYPE_OPENGLES3 ||
+ context_type == CONTEXT_TYPE_WEBGL2 ||
+ feature_info_->feature_flags().ext_draw_buffers) {
GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &max_color_attachments_);
if (max_color_attachments_ < 1)
max_color_attachments_ = 1;
diff --git a/chromium/gpu/command_buffer/service/context_group_unittest.cc b/chromium/gpu/command_buffer/service/context_group_unittest.cc
index 28fb63a9d35..0cb509858f7 100644
--- a/chromium/gpu/command_buffer/service/context_group_unittest.cc
+++ b/chromium/gpu/command_buffer/service/context_group_unittest.cc
@@ -11,6 +11,7 @@
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/service_discardable_manager.h"
@@ -43,7 +44,7 @@ class ContextGroupTest : public GpuServiceTest {
protected:
void SetUp() override {
GpuServiceTest::SetUp();
- decoder_.reset(new MockGLES2Decoder(&command_buffer_service_));
+ decoder_.reset(new MockGLES2Decoder(&command_buffer_service_, &outputter_));
scoped_refptr<FeatureInfo> feature_info = new FeatureInfo;
group_ = scoped_refptr<ContextGroup>(new ContextGroup(
gpu_preferences_, false, &mailbox_manager_,
@@ -59,6 +60,7 @@ class ContextGroupTest : public GpuServiceTest {
ServiceDiscardableManager discardable_manager_;
FakeCommandBufferServiceBase command_buffer_service_;
MailboxManagerImpl mailbox_manager_;
+ TraceOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> decoder_;
scoped_refptr<ContextGroup> group_;
};
@@ -116,8 +118,9 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) {
TEST_F(ContextGroupTest, MultipleContexts) {
FakeCommandBufferServiceBase command_buffer_service2;
+ TraceOutputter outputter;
std::unique_ptr<MockGLES2Decoder> decoder2_(
- new MockGLES2Decoder(&command_buffer_service2));
+ new MockGLES2Decoder(&command_buffer_service2, &outputter));
TestHelper::SetupContextGroupInitExpectations(
gl_.get(), DisallowedFeatures(), "", "",
CONTEXT_TYPE_OPENGLES2, kBindGeneratesResource);
diff --git a/chromium/gpu/command_buffer/service/create_gr_gl_interface.cc b/chromium/gpu/command_buffer/service/create_gr_gl_interface.cc
index 08c3c64a6c2..691dbc84e8a 100644
--- a/chromium/gpu/command_buffer/service/create_gr_gl_interface.cc
+++ b/chromium/gpu/command_buffer/service/create_gr_gl_interface.cc
@@ -11,6 +11,12 @@ namespace gles2 {
namespace {
+template <typename R, typename... Args>
+GrGLFunction<R (*)(Args...)> bind(R (gl::GLApi::*func)(Args...),
+ gl::GLApi* api) {
+ return [func, api](Args... args) { return (api->*func)(args...); };
+}
+
const GLubyte* GetStringHook(const char* version_string, GLenum name) {
switch (name) {
case GL_VERSION:
@@ -43,6 +49,7 @@ const char* kBlacklistExtensions[] = {
sk_sp<const GrGLInterface> CreateGrGLInterface(
const gl::GLVersionInfo& version_info) {
gl::ProcsGL* gl = &gl::g_current_gl_driver->fn;
+ gl::GLApi* api = gl::g_current_gl_context;
GrGLStandard standard =
version_info.is_es ? kGLES_GrGLStandard : kGL_GrGLStandard;
@@ -60,12 +67,14 @@ sk_sp<const GrGLInterface> CreateGrGLInterface(
return GetStringHook(fake_version, name);
};
} else {
- get_string = gl->glGetStringFn;
+ get_string = bind(&gl::GLApi::glGetStringFn, api);
}
+ auto get_stringi = bind(&gl::GLApi::glGetStringiFn, api);
+ auto get_integerv = bind(&gl::GLApi::glGetIntegervFn, api);
+
GrGLExtensions extensions;
- if (!extensions.init(standard, get_string, gl->glGetStringiFn,
- gl->glGetIntegervFn)) {
+ if (!extensions.init(standard, get_string, get_stringi, get_integerv)) {
LOG(ERROR) << "Failed to initialize extensions";
return nullptr;
}
@@ -113,6 +122,7 @@ sk_sp<const GrGLInterface> CreateGrGLInterface(
functions->fDepthMask = gl->glDepthMaskFn;
functions->fDisable = gl->glDisableFn;
functions->fDisableVertexAttribArray = gl->glDisableVertexAttribArrayFn;
+ functions->fDiscardFramebuffer = gl->glDiscardFramebufferEXTFn;
functions->fDrawArrays = gl->glDrawArraysFn;
functions->fDrawBuffer = gl->glDrawBufferFn;
functions->fDrawBuffers = gl->glDrawBuffersARBFn;
@@ -249,6 +259,10 @@ sk_sp<const GrGLInterface> CreateGrGLInterface(
functions->fBindRenderbuffer = gl->glBindRenderbufferEXTFn;
functions->fRenderbufferStorageMultisample =
gl->glRenderbufferStorageMultisampleEXTFn;
+ functions->fFramebufferTexture2DMultisample =
+ gl->glFramebufferTexture2DMultisampleEXTFn;
+ functions->fRenderbufferStorageMultisampleES2EXT =
+ gl->glRenderbufferStorageMultisampleEXTFn;
functions->fBlitFramebuffer = gl->glBlitFramebufferFn;
functions->fMatrixLoadf = gl->glMatrixLoadfEXTFn;
diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc
index f038996b228..b8851b35169 100644
--- a/chromium/gpu/command_buffer/service/feature_info.cc
+++ b/chromium/gpu/command_buffer/service/feature_info.cc
@@ -177,6 +177,35 @@ bool IsWebGLDrawBuffersSupported(bool webglCompatibilityContext,
} // anonymous namespace.
+namespace {
+
+enum GpuTextureResultR16_L16 {
+ // Values synced with 'GpuTextureResultR16_L16' in
+ // src/tools/metrics/histograms/histograms.xml
+ kHaveNone = 0,
+ kHaveR16 = 1,
+ kHaveL16 = 2,
+ kHaveR16AndL16 = 3,
+ kMax = kHaveR16AndL16
+};
+
+// TODO(riju): For UMA, remove after crbug.com/759456 is resolved.
+bool g_r16_is_present;
+bool g_l16_is_present;
+
+GpuTextureResultR16_L16 GpuTextureUMAHelper() {
+ if (g_r16_is_present && g_l16_is_present) {
+ return GpuTextureResultR16_L16::kHaveR16AndL16;
+ } else if (g_r16_is_present) {
+ return GpuTextureResultR16_L16::kHaveR16;
+ } else if (g_l16_is_present) {
+ return GpuTextureResultR16_L16::kHaveL16;
+ }
+ return GpuTextureResultR16_L16::kHaveNone;
+}
+
+} // anonymous namespace.
+
FeatureInfo::FeatureFlags::FeatureFlags() {}
FeatureInfo::FeatureInfo() {
@@ -1296,8 +1325,11 @@ void FeatureInfo::InitializeFeatures() {
UMA_HISTOGRAM_BOOLEAN("GPU.TextureRG", feature_flags_.ext_texture_rg);
if (gl_version_info_->is_desktop_core_profile ||
+ (gl_version_info_->IsAtLeastGL(2, 1) &&
+ gl::HasExtension(extensions, "GL_ARB_texture_rg")) ||
gl::HasExtension(extensions, "GL_EXT_texture_norm16")) {
feature_flags_.ext_texture_norm16 = true;
+ g_r16_is_present = true;
AddExtensionString("GL_EXT_texture_norm16");
// Note: EXT_texture_norm16 is not exposed through WebGL API so we validate
@@ -1308,6 +1340,10 @@ void FeatureInfo::InitializeFeatures() {
validators_.texture_unsized_internal_format.AddValue(GL_RED_EXT);
}
+ UMA_HISTOGRAM_ENUMERATION(
+ "GPU.TextureR16Ext_LuminanceF16", GpuTextureUMAHelper(),
+ static_cast<int>(GpuTextureResultR16_L16::kMax) + 1);
+
bool has_opengl_dual_source_blending =
gl_version_info_->IsAtLeastGL(3, 3) ||
(gl_version_info_->IsAtLeastGL(3, 2) &&
@@ -1385,6 +1421,11 @@ void FeatureInfo::InitializeFeatures() {
gl::HasExtension(extensions, "GL_CHROMIUM_texture_filtering_hint");
feature_flags_.ext_pixel_buffer_object =
gl::HasExtension(extensions, "GL_NV_pixel_buffer_object");
+ feature_flags_.oes_rgb8_rgba8 =
+ gl::HasExtension(extensions, "GL_OES_rgb8_rgba8");
+ feature_flags_.angle_robust_resource_initialization =
+ gl::HasExtension(extensions, "GL_ANGLE_robust_resource_initialization");
+ feature_flags_.nv_fence = gl::HasExtension(extensions, "GL_NV_fence");
}
void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
@@ -1406,8 +1447,14 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
// rendered to via framebuffer objects.
if (gl::HasExtension(extensions, "GL_EXT_color_buffer_float"))
enable_ext_color_buffer_float = true;
- if (gl::HasExtension(extensions, "GL_EXT_color_buffer_half_float"))
+ if (gl::HasExtension(extensions, "GL_EXT_color_buffer_half_float")) {
+ // TODO(zmo): even if the underlying driver reports the extension, WebGL
+ // version of the extension requires RGBA16F to be color-renderable,
+ // whereas the OpenGL ES extension only requires one of the format to be
+ // color-renderable. So we still need to do some verification before
+ // exposing the extension.
enable_ext_color_buffer_half_float = true;
+ }
if (gl::HasExtension(extensions, "GL_ARB_texture_float") ||
gl_version_info_->is_desktop_core_profile) {
@@ -1541,28 +1588,20 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
// Likewise for EXT_color_buffer_half_float on ES2 contexts. On desktop,
// require at least GL 3.0, to ensure that all formats are defined.
if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float &&
- (gl_version_info_->is_es || gl_version_info_->IsAtLeastGL(3, 0))) {
- bool full_half_float_support = true;
- GLenum internal_formats[] = {
- GL_R16F, GL_RG16F, GL_RGBA16F,
- };
- GLenum formats[] = {
- GL_RED, GL_RG, GL_RGBA,
- };
- GLenum data_type = GL_FLOAT;
- if (gl_version_info_->is_es2)
- data_type = GL_HALF_FLOAT_OES;
- if (gl_version_info_->is_es3)
- data_type = GL_HALF_FLOAT;
- DCHECK_EQ(arraysize(internal_formats), arraysize(formats));
- for (size_t i = 0; i < arraysize(formats); ++i) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], width, width, 0,
- formats[i], data_type, NULL);
- full_half_float_support &=
- glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
- GL_FRAMEBUFFER_COMPLETE;
- }
- enable_ext_color_buffer_half_float = full_half_float_support;
+ (gl_version_info_->IsAtLeastGLES(3, 0) ||
+ gl_version_info_->IsAtLeastGL(3, 0))) {
+ // EXT_color_buffer_half_float requires at least one of the formats is
+ // supported to be color-renderable. WebGL's extension requires RGBA16F
+ // to be the supported effective format. Here we only expose the extension
+ // if RGBA16F is color-renderable.
+ GLenum internal_format = GL_RGBA16F;
+ GLenum format = GL_RGBA;
+ GLenum data_type = GL_HALF_FLOAT;
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, width, 0, format,
+ data_type, nullptr);
+ enable_ext_color_buffer_half_float =
+ (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
+ GL_FRAMEBUFFER_COMPLETE);
}
glDeleteFramebuffersEXT(1, &fb_id);
@@ -1616,6 +1655,9 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
GL_LUMINANCE_ALPHA16F_EXT);
}
}
+
+ g_l16_is_present =
+ enable_texture_half_float && feature_flags_.ext_texture_storage;
}
bool FeatureInfo::IsES3Capable() const {
diff --git a/chromium/gpu/command_buffer/service/feature_info.h b/chromium/gpu/command_buffer/service/feature_info.h
index 6fe9fbe527e..bb5daf39d41 100644
--- a/chromium/gpu/command_buffer/service/feature_info.h
+++ b/chromium/gpu/command_buffer/service/feature_info.h
@@ -119,6 +119,9 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool khr_robustness = false;
bool ext_robustness = false;
bool ext_pixel_buffer_object = false;
+ bool oes_rgb8_rgba8 = false;
+ bool angle_robust_resource_initialization = false;
+ bool nv_fence = false;
};
FeatureInfo();
diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.cc b/chromium/gpu/command_buffer/service/framebuffer_manager.cc
index 366c5085c87..86ef51edec1 100644
--- a/chromium/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/chromium/gpu/command_buffer/service/framebuffer_manager.cc
@@ -722,6 +722,7 @@ GLenum Framebuffer::IsPossiblyComplete(const FeatureInfo* feature_info) const {
// Since DirectX doesn't allow attachments to be of different sizes,
// even though ES3 allows it, it is still forbidden to ensure consistent
// behaviors across platforms.
+ // Note: Framebuffer::GetFramebufferValidSize relies on this behavior.
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
}
@@ -1050,6 +1051,19 @@ const Framebuffer::Attachment* Framebuffer::GetReadBufferAttachment() const {
return GetAttachment(read_buffer_);
}
+gfx::Size Framebuffer::GetFramebufferValidSize() const {
+ // This DCHECK ensures the framebuffer was already checked to be complete.
+ DCHECK(manager_->IsComplete(this));
+
+ // IsPossiblyComplete ensures that there is at least one attachment, and that
+ // all of the attachments have the same dimensions. So it's okay to just pick
+ // any arbitrary attachment and return it as the min size.
+ auto it = attachments_.begin();
+ DCHECK(it != attachments_.end());
+ const auto& attachment = it->second;
+ return gfx::Size(attachment->width(), attachment->height());
+}
+
bool FramebufferManager::GetClientId(
GLuint service_id, GLuint* client_id) const {
// This doesn't need to be fast. It's only used during slow queries.
@@ -1080,8 +1094,7 @@ void FramebufferManager::MarkAsComplete(
framebuffer->MarkAsComplete(framebuffer_state_change_count_);
}
-bool FramebufferManager::IsComplete(
- Framebuffer* framebuffer) {
+bool FramebufferManager::IsComplete(const Framebuffer* framebuffer) {
DCHECK(framebuffer);
return framebuffer->framebuffer_complete_state_count_id() ==
framebuffer_state_change_count_;
diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.h b/chromium/gpu/command_buffer/service/framebuffer_manager.h
index 09ab0923206..c29dc649b11 100644
--- a/chromium/gpu/command_buffer/service/framebuffer_manager.h
+++ b/chromium/gpu/command_buffer/service/framebuffer_manager.h
@@ -133,6 +133,10 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
const Attachment* GetReadBufferAttachment() const;
+ // Returns the max dimensions which fit inside all of the attachments.
+ // Can only be called after the framebuffer has been checked to be complete.
+ gfx::Size GetFramebufferValidSize() const;
+
GLsizei GetSamples() const;
bool IsDeleted() const {
@@ -345,7 +349,7 @@ class GPU_EXPORT FramebufferManager {
void MarkAsComplete(Framebuffer* framebuffer);
- bool IsComplete(Framebuffer* framebuffer);
+ bool IsComplete(const Framebuffer* framebuffer);
void IncFramebufferStateChangeCount() {
// make sure this is never 0.
diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index ebe5fc8cafa..6a96d4c1e87 100644
--- a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -11,6 +11,7 @@
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/renderbuffer_manager.h"
#include "gpu/command_buffer/service/service_discardable_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
@@ -150,7 +151,7 @@ class FramebufferInfoTestBase : public GpuServiceTest {
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
extensions, "", gl_version, context_type_);
feature_info_->InitializeForTesting(context_type_);
- decoder_.reset(new MockGLES2Decoder(&command_buffer_service_));
+ decoder_.reset(new MockGLES2Decoder(&command_buffer_service_, &outputter_));
manager_.CreateFramebuffer(kClient1Id, kService1Id);
error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
framebuffer_ = manager_.GetFramebuffer(kClient1Id);
@@ -167,6 +168,7 @@ class FramebufferInfoTestBase : public GpuServiceTest {
std::unique_ptr<RenderbufferManager> renderbuffer_manager_;
std::unique_ptr<MockErrorState> error_state_;
FakeCommandBufferServiceBase command_buffer_service_;
+ TraceOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> decoder_;
};
diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc b/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
index cdac976c64e..e2566c9ec51 100644
--- a/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
+++ b/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
@@ -7,6 +7,7 @@
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "ui/gl/gl_context_stub.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
@@ -21,11 +22,12 @@ using testing::Return;
class GLContextVirtualTest : public GpuServiceTest {
public:
GLContextVirtualTest()
- : decoder_(new gles2::MockGLES2Decoder(&command_buffer_service_)) {}
+ : decoder_(new MockGLES2Decoder(&command_buffer_service_, &outputter_)) {}
~GLContextVirtualTest() override {}
protected:
FakeCommandBufferServiceBase command_buffer_service_;
+ TraceOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> decoder_;
};
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 2da74f06c8a..a5446a0059a 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -14,10 +14,10 @@
#include <list>
#include <map>
#include <memory>
-#include <queue>
#include "base/callback.h"
#include "base/callback_helpers.h"
+#include "base/containers/queue.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
@@ -496,11 +496,11 @@ uint32_t GLES2Decoder::GetAndClearBackbufferClearBitsForTest() {
return 0;
}
-GLES2Decoder::GLES2Decoder(CommandBufferServiceBase* command_buffer_service)
- : CommonDecoder(command_buffer_service),
- initialized_(false),
- debug_(false),
- log_commands_(false) {}
+GLES2Decoder::GLES2Decoder(CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter)
+ : CommonDecoder(command_buffer_service), outputter_(outputter) {
+ DCHECK(outputter_);
+}
GLES2Decoder::~GLES2Decoder() {
}
@@ -519,6 +519,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
public:
GLES2DecoderImpl(GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group);
~GLES2DecoderImpl() override;
@@ -2470,7 +2471,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
bool gpu_trace_commands_;
bool gpu_debug_commands_;
- std::queue<FenceCallback> pending_readpixel_fences_;
+ base::queue<FenceCallback> pending_readpixel_fences_;
// After a second fence is inserted, both the GpuChannelMessageQueue and
// CommandExecutor are descheduled. Once the first fence has completed, both
@@ -2521,7 +2522,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
};
-const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
+constexpr GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
#define GLES2_CMD_OP(name) \
{ \
&GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
@@ -3096,19 +3097,21 @@ GLenum BackFramebuffer::CheckStatus() {
GLES2Decoder* GLES2Decoder::Create(
GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group) {
if (group->use_passthrough_cmd_decoder()) {
return new GLES2DecoderPassthroughImpl(client, command_buffer_service,
- group);
+ outputter, group);
}
- return new GLES2DecoderImpl(client, command_buffer_service, group);
+ return new GLES2DecoderImpl(client, command_buffer_service, outputter, group);
}
GLES2DecoderImpl::GLES2DecoderImpl(
GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group)
- : GLES2Decoder(command_buffer_service),
+ : GLES2Decoder(command_buffer_service, outputter),
client_(client),
group_(group),
logger_(&debug_marker_manager_, client_),
@@ -3399,7 +3402,7 @@ bool GLES2DecoderImpl::Initialize(
offscreen_single_buffer_ = attrib_helper.single_buffer;
if (gl_version_info().is_es) {
- const bool rgb8_supported = context_->HasExtension("GL_OES_rgb8_rgba8");
+ const bool rgb8_supported = features().oes_rgb8_rgba8;
// The only available default render buffer formats in GLES2 have very
// little precision. Don't enable multisampling unless 8-bit render
// buffer formats are available--instead fall back to 8-bit textures.
@@ -3920,20 +3923,11 @@ Capabilities GLES2DecoderImpl::GetCapabilities() {
caps.occlusion_query = feature_info_->feature_flags().occlusion_query;
caps.occlusion_query_boolean =
feature_info_->feature_flags().occlusion_query_boolean;
- caps.timer_queries =
- query_manager_->GPUTimingAvailable();
- caps.disable_multisampling_color_mask_usage =
- workarounds().disable_multisampling_color_mask_usage;
+ caps.timer_queries = query_manager_->GPUTimingAvailable();
caps.gpu_rasterization =
group_->gpu_feature_info()
.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] ==
kGpuFeatureStatusEnabled;
- caps.disable_webgl_rgb_multisampling_usage =
- workarounds().disable_webgl_rgb_multisampling_usage;
- caps.software_to_accelerated_canvas_upgrade =
- !workarounds().disable_software_to_accelerated_canvas_upgrade;
- caps.emulate_rgb_buffer_with_rgba =
- workarounds().disable_gl_rgb_format;
if (workarounds().disable_non_empty_post_sub_buffers_for_onscreen_surfaces &&
!surface_->IsOffscreen()) {
caps.disable_non_empty_post_sub_buffers = true;
@@ -3942,6 +3936,7 @@ Capabilities GLES2DecoderImpl::GetCapabilities() {
group_->gpu_preferences().enable_threaded_texture_mailboxes) {
caps.disable_2d_canvas_copy_on_write = true;
}
+ caps.texture_npot = feature_info_->feature_flags().npot_ok;
return caps;
}
@@ -4081,6 +4076,10 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
if (workarounds().rewrite_float_unary_minus_operator)
driver_bug_workarounds |= SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR;
+ // Initialize uninitialized locals by default
+ if (!workarounds().dont_initialize_uninitialized_locals)
+ driver_bug_workarounds |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
+
resources.WEBGL_debug_shader_precision =
group_->gpu_preferences().emulate_shader_precision;
@@ -4589,12 +4588,7 @@ bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
gfx::Size GLES2DecoderImpl::GetBoundReadFramebufferSize() {
Framebuffer* framebuffer = GetBoundReadFramebuffer();
if (framebuffer) {
- const Framebuffer::Attachment* attachment =
- framebuffer->GetReadBufferAttachment();
- if (attachment) {
- return gfx::Size(attachment->width(), attachment->height());
- }
- return gfx::Size(0, 0);
+ return framebuffer->GetFramebufferValidSize();
} else if (offscreen_target_frame_buffer_.get()) {
return offscreen_size_;
} else {
@@ -4974,7 +4968,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
// Release all fences now, because some fence types need the context to be
// current on destruction.
- pending_readpixel_fences_ = std::queue<FenceCallback>();
+ pending_readpixel_fences_ = base::queue<FenceCallback>();
// Need to release these before releasing |group_| which may own the
// ShaderTranslatorCache.
@@ -10424,10 +10418,8 @@ error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
if (!features().angle_instanced_arrays)
return error::kUnknownCommand;
- return DoDrawArrays("glDrawArraysIntancedANGLE",
- true,
- static_cast<GLenum>(c.mode),
- static_cast<GLint>(c.first),
+ return DoDrawArrays("glDrawArraysInstancedANGLE", true,
+ static_cast<GLenum>(c.mode), static_cast<GLint>(c.first),
static_cast<GLsizei>(c.count),
static_cast<GLsizei>(c.primcount));
}
@@ -11814,9 +11806,6 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
"format and type incompatible with the current read framebuffer");
return error::kNoError;
}
- if (type == GL_HALF_FLOAT_OES && !gl_version_info().is_es) {
- type = GL_HALF_FLOAT;
- }
if (width == 0 || height == 0) {
return error::kNoError;
}
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h
index 688537a3ba3..b7a07e3f478 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -48,6 +48,7 @@ class FramebufferManager;
class GLES2Util;
class ImageManager;
class Logger;
+class Outputter;
class QueryManager;
class ShaderTranslatorInterface;
class Texture;
@@ -127,6 +128,7 @@ class GPU_EXPORT GLES2Decoder : public CommonDecoder, public AsyncAPIInterface {
// Creates a decoder.
static GLES2Decoder* Create(GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group);
~GLES2Decoder() override;
@@ -157,6 +159,8 @@ class GPU_EXPORT GLES2Decoder : public CommonDecoder, public AsyncAPIInterface {
log_commands_ = log_commands;
}
+ Outputter* outputter() const { return outputter_; }
+
virtual base::WeakPtr<GLES2Decoder> AsWeakPtr() = 0;
// Initializes the graphics context. Can create an offscreen
@@ -342,14 +346,17 @@ class GPU_EXPORT GLES2Decoder : public CommonDecoder, public AsyncAPIInterface {
bool can_bind_to_sampler) = 0;
protected:
- explicit GLES2Decoder(CommandBufferServiceBase* command_buffer_service);
+ GLES2Decoder(CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter);
base::StringPiece GetLogPrefix() override;
private:
- bool initialized_;
- bool debug_;
- bool log_commands_;
+ bool initialized_ = false;
+ bool debug_ = false;
+ bool log_commands_ = false;
+ Outputter* outputter_ = nullptr;
+
DISALLOW_COPY_AND_ASSIGN(GLES2Decoder);
};
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc
index 5df3d06eb0c..50511a581dc 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc
@@ -10,8 +10,9 @@ namespace gpu {
namespace gles2 {
MockGLES2Decoder::MockGLES2Decoder(
- CommandBufferServiceBase* command_buffer_service)
- : GLES2Decoder(command_buffer_service), weak_ptr_factory_(this) {
+ CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter)
+ : GLES2Decoder(command_buffer_service, outputter), weak_ptr_factory_(this) {
ON_CALL(*this, MakeCurrent())
.WillByDefault(testing::Return(true));
}
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index a694ba2e8e2..5a85501e7d1 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -36,7 +36,8 @@ struct ContextState;
class MockGLES2Decoder : public GLES2Decoder {
public:
- explicit MockGLES2Decoder(CommandBufferServiceBase* command_buffer_service);
+ MockGLES2Decoder(CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter);
virtual ~MockGLES2Decoder();
base::WeakPtr<GLES2Decoder> AsWeakPtr() override;
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index f033ced36c0..4d427bec788 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -46,6 +46,31 @@ bool GetClientID(const ClientServiceMap<ClientType, ServiceType>* map,
return true;
};
+void ResizeRenderbuffer(GLuint renderbuffer,
+ const gfx::Size& size,
+ GLsizei samples,
+ GLenum internal_format,
+ const FeatureInfo* feature_info) {
+ ScopedRenderbufferBindingReset scoped_renderbuffer_reset;
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER, renderbuffer);
+ if (samples > 0) {
+ if (feature_info->feature_flags().angle_framebuffer_multisample) {
+ glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples,
+ internal_format, size.width(),
+ size.height());
+ } else {
+ DCHECK(feature_info->gl_version_info().is_es3);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ internal_format, size.width(),
+ size.height());
+ }
+ } else {
+ glRenderbufferStorageEXT(GL_RENDERBUFFER, internal_format, size.width(),
+ size.height());
+ }
+}
+
} // anonymous namespace
PassthroughResources::PassthroughResources() {}
@@ -90,6 +115,34 @@ void PassthroughResources::Destroy(bool have_context) {
texture_object_map.clear();
}
+ScopedFramebufferBindingReset::ScopedFramebufferBindingReset()
+ : draw_framebuffer_(0), read_framebuffer_(0) {
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer_);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer_);
+}
+
+ScopedFramebufferBindingReset::~ScopedFramebufferBindingReset() {
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer_);
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer_);
+}
+
+ScopedRenderbufferBindingReset::ScopedRenderbufferBindingReset()
+ : renderbuffer_(0) {
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &renderbuffer_);
+}
+
+ScopedRenderbufferBindingReset::~ScopedRenderbufferBindingReset() {
+ glBindRenderbufferEXT(GL_RENDERBUFFER, renderbuffer_);
+}
+
+ScopedTexture2DBindingReset::ScopedTexture2DBindingReset() : texture_(0) {
+ glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &texture_);
+}
+
+ScopedTexture2DBindingReset::~ScopedTexture2DBindingReset() {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+}
+
GLES2DecoderPassthroughImpl::PendingQuery::PendingQuery() = default;
GLES2DecoderPassthroughImpl::PendingQuery::~PendingQuery() = default;
GLES2DecoderPassthroughImpl::PendingQuery::PendingQuery(const PendingQuery&) =
@@ -125,11 +178,237 @@ GLES2DecoderPassthroughImpl::BoundTexture::operator=(const BoundTexture&) =
GLES2DecoderPassthroughImpl::BoundTexture&
GLES2DecoderPassthroughImpl::BoundTexture::operator=(BoundTexture&&) = default;
+GLES2DecoderPassthroughImpl::PendingReadPixels::PendingReadPixels() = default;
+GLES2DecoderPassthroughImpl::PendingReadPixels::~PendingReadPixels() = default;
+GLES2DecoderPassthroughImpl::PendingReadPixels::PendingReadPixels(
+ PendingReadPixels&&) = default;
+GLES2DecoderPassthroughImpl::PendingReadPixels&
+GLES2DecoderPassthroughImpl::PendingReadPixels::operator=(PendingReadPixels&&) =
+ default;
+
+GLES2DecoderPassthroughImpl::EmulatedColorBuffer::EmulatedColorBuffer(
+ const EmulatedDefaultFramebufferFormat& format_in)
+ : format(format_in) {
+ ScopedTexture2DBindingReset scoped_texture_reset;
+
+ GLuint color_buffer_texture = 0;
+ glGenTextures(1, &color_buffer_texture);
+ glBindTexture(GL_TEXTURE_2D, color_buffer_texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ texture = new TexturePassthrough(color_buffer_texture, GL_TEXTURE_2D);
+}
+
+GLES2DecoderPassthroughImpl::EmulatedColorBuffer::~EmulatedColorBuffer() =
+ default;
+
+bool GLES2DecoderPassthroughImpl::EmulatedColorBuffer::Resize(
+ const gfx::Size& new_size) {
+ if (size == new_size) {
+ return true;
+ }
+ size = new_size;
+
+ ScopedTexture2DBindingReset scoped_texture_reset;
+
+ DCHECK(texture);
+ DCHECK(texture->target() == GL_TEXTURE_2D);
+
+ glBindTexture(texture->target(), texture->service_id());
+ glTexImage2D(texture->target(), 0, format.color_texture_internal_format,
+ size.width(), size.height(), 0, format.color_texture_format,
+ format.color_texture_type, nullptr);
+
+ return true;
+}
+
+void GLES2DecoderPassthroughImpl::EmulatedColorBuffer::Destroy(
+ bool have_context) {
+ if (!have_context) {
+ texture->MarkContextLost();
+ }
+ texture = nullptr;
+}
+
+GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::
+ EmulatedDefaultFramebuffer(
+ const EmulatedDefaultFramebufferFormat& format_in,
+ const FeatureInfo* feature_info)
+ : format(format_in) {
+ ScopedFramebufferBindingReset scoped_fbo_reset;
+ ScopedRenderbufferBindingReset scoped_renderbuffer_reset;
+
+ glGenFramebuffersEXT(1, &framebuffer_service_id);
+ glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_service_id);
+
+ if (format.samples > 0) {
+ glGenRenderbuffersEXT(1, &color_buffer_service_id);
+ glBindRenderbufferEXT(GL_RENDERBUFFER, color_buffer_service_id);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, color_buffer_service_id);
+ } else {
+ color_texture.reset(new EmulatedColorBuffer(format));
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ color_texture->texture->service_id(), 0);
+ }
+
+ if (format.depth_stencil_internal_format != GL_NONE) {
+ DCHECK(format.depth_internal_format == GL_NONE &&
+ format.stencil_internal_format == GL_NONE);
+ glGenRenderbuffersEXT(1, &depth_stencil_buffer_service_id);
+ glBindRenderbufferEXT(GL_RENDERBUFFER, depth_stencil_buffer_service_id);
+ if (feature_info->gl_version_info().IsAtLeastGLES(3, 0) ||
+ feature_info->feature_flags().angle_webgl_compatibility) {
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ depth_stencil_buffer_service_id);
+ } else {
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ depth_stencil_buffer_service_id);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ depth_stencil_buffer_service_id);
+ }
+ } else {
+ if (format.depth_internal_format != GL_NONE) {
+ glGenRenderbuffersEXT(1, &depth_buffer_service_id);
+ glBindRenderbufferEXT(GL_RENDERBUFFER, depth_buffer_service_id);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer_service_id);
+ }
+
+ if (format.stencil_internal_format != GL_NONE) {
+ glGenRenderbuffersEXT(1, &stencil_buffer_service_id);
+ glBindRenderbufferEXT(GL_RENDERBUFFER, stencil_buffer_service_id);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, stencil_buffer_service_id);
+ }
+ }
+}
+
+GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::
+ ~EmulatedDefaultFramebuffer() = default;
+
+std::unique_ptr<GLES2DecoderPassthroughImpl::EmulatedColorBuffer>
+GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::SetColorBuffer(
+ std::unique_ptr<EmulatedColorBuffer> new_color_buffer) {
+ DCHECK(color_texture != nullptr && new_color_buffer != nullptr);
+ DCHECK(color_texture->size == new_color_buffer->size);
+ std::unique_ptr<EmulatedColorBuffer> old_buffer(std::move(color_texture));
+ color_texture = std::move(new_color_buffer);
+
+ // Bind the new texture to this FBO
+ ScopedFramebufferBindingReset scoped_fbo_reset;
+ glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_service_id);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ color_texture->texture->service_id(), 0);
+
+ return old_buffer;
+}
+
+void GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::Blit(
+ EmulatedColorBuffer* target) {
+ DCHECK(target != nullptr);
+ DCHECK(target->size == size);
+
+ ScopedFramebufferBindingReset scoped_fbo_reset;
+
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER, framebuffer_service_id);
+
+ GLuint temp_fbo;
+ glGenFramebuffersEXT(1, &temp_fbo);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, temp_fbo);
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, target->texture->service_id(), 0);
+
+ glBlitFramebufferANGLE(0, 0, size.width(), size.height(), 0, 0,
+ target->size.width(), target->size.height(),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ glDeleteFramebuffersEXT(1, &temp_fbo);
+}
+
+bool GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::Resize(
+ const gfx::Size& new_size,
+ const FeatureInfo* feature_info) {
+ if (size == new_size) {
+ return true;
+ }
+ size = new_size;
+
+ if (color_buffer_service_id != 0) {
+ ResizeRenderbuffer(color_buffer_service_id, size, format.samples,
+ format.color_renderbuffer_internal_format, feature_info);
+ }
+ if (color_texture) {
+ if (!color_texture->Resize(size)) {
+ return false;
+ }
+ }
+ if (depth_stencil_buffer_service_id != 0) {
+ ResizeRenderbuffer(depth_stencil_buffer_service_id, size, format.samples,
+ format.depth_stencil_internal_format, feature_info);
+ }
+ if (depth_buffer_service_id != 0) {
+ ResizeRenderbuffer(depth_buffer_service_id, size, format.samples,
+ format.depth_internal_format, feature_info);
+ }
+ if (stencil_buffer_service_id != 0) {
+ ResizeRenderbuffer(stencil_buffer_service_id, size, format.samples,
+ format.stencil_internal_format, feature_info);
+ }
+
+ // Check that the framebuffer is complete
+ {
+ ScopedFramebufferBindingReset scoped_fbo_reset;
+ glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_service_id);
+ if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) !=
+ GL_FRAMEBUFFER_COMPLETE) {
+ LOG(ERROR)
+ << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer failed "
+ << "because the resulting framebuffer was not complete.";
+ return false;
+ }
+ }
+
+ DCHECK(color_texture == nullptr || color_texture->size == size);
+
+ return true;
+}
+
+void GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer::Destroy(
+ bool have_context) {
+ if (have_context) {
+ glDeleteFramebuffersEXT(1, &framebuffer_service_id);
+ framebuffer_service_id = 0;
+
+ glDeleteRenderbuffersEXT(1, &color_buffer_service_id);
+ color_buffer_service_id = 0;
+
+ glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_service_id);
+ color_buffer_service_id = 0;
+
+ glDeleteRenderbuffersEXT(1, &depth_buffer_service_id);
+ depth_buffer_service_id = 0;
+
+ glDeleteRenderbuffersEXT(1, &stencil_buffer_service_id);
+ stencil_buffer_service_id = 0;
+ }
+ if (color_texture) {
+ color_texture->Destroy(have_context);
+ }
+}
+
GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(
GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group)
- : GLES2Decoder(command_buffer_service),
+ : GLES2Decoder(command_buffer_service, outputter),
client_(client),
commands_to_process_(0),
debug_marker_manager_(),
@@ -139,6 +418,13 @@ GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(
offscreen_(false),
group_(group),
feature_info_(new FeatureInfo(group->feature_info()->workarounds())),
+ emulated_back_buffer_(nullptr),
+ offscreen_single_buffer_(false),
+ offscreen_target_buffer_preserved_(false),
+ create_color_buffer_count_for_test_(0),
+ max_2d_texture_size_(0),
+ bound_draw_framebuffer_(0),
+ bound_read_framebuffer_(0),
gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
gpu_trace_level_(2),
@@ -147,6 +433,7 @@ GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(
has_robustness_extension_(false),
context_lost_(false),
reset_by_robustness_extension_(false),
+ lose_context_when_out_of_memory_(false),
weak_ptr_factory_(this) {
DCHECK(client);
DCHECK(group);
@@ -282,6 +569,61 @@ bool GLES2DecoderPassthroughImpl::Initialize(
return false;
}
+ // Extensions that are enabled via emulation on the client side or needed for
+ // basic command buffer functionality. Make sure they are always enabled.
+ if (IsWebGLContextType(attrib_helper.context_type)) {
+ static constexpr const char* kEnableByDefaultExtensions[] = {
+ "GL_ANGLE_depth_texture",
+ "GL_ANGLE_framebuffer_blit",
+ "GL_ANGLE_framebuffer_multisample",
+ "GL_ANGLE_instanced_arrays",
+ "GL_ANGLE_pack_reverse_row_order",
+ "GL_ANGLE_texture_compression_dxt3",
+ "GL_ANGLE_texture_compression_dxt5",
+ "GL_ANGLE_texture_usage",
+ "GL_ANGLE_translated_shader_source",
+ "GL_CHROMIUM_bind_uniform_location",
+ "GL_CHROMIUM_framebuffer_mixed_samples",
+ "GL_CHROMIUM_path_rendering",
+ "GL_CHROMIUM_sync_query",
+ "GL_EXT_blend_minmax",
+ "GL_EXT_debug_marker",
+ "GL_EXT_discard_framebuffer",
+ "GL_EXT_disjoint_timer_query",
+ "GL_EXT_occlusion_query_boolean",
+ "GL_EXT_sRGB",
+ "GL_EXT_sRGB_write_control",
+ "GL_EXT_texture_compression_dxt1",
+ "GL_EXT_texture_compression_s3tc_srgb",
+ "GL_EXT_texture_norm16",
+ "GL_EXT_texture_rg",
+ "GL_EXT_texture_sRGB_decode",
+ "GL_EXT_texture_storage",
+ "GL_EXT_unpack_subimage",
+ "GL_KHR_texture_compression_astc_hdr",
+ "GL_KHR_texture_compression_astc_ldr",
+ "GL_NV_fence",
+ "GL_NV_pack_subimage",
+ "GL_OES_compressed_ETC1_RGB8_texture",
+ "GL_OES_depth32",
+ "GL_OES_fbo_render_mipmap",
+ "GL_OES_packed_depth_stencil",
+ "GL_OES_rgb8_rgba8",
+ "GL_OES_vertex_array_object",
+ };
+
+ // Grab the extensions that are requestable
+ gl::ExtensionSet requestable_extensions(
+ gl::GetRequestableGLExtensionsFromCurrentContext());
+ for (const char* default_extension : kEnableByDefaultExtensions) {
+ if (gl::HasExtension(requestable_extensions, default_extension)) {
+ // Request the intersection of the two sets
+ glRequestExtensionANGLE(default_extension);
+ }
+ }
+ context->ReinitializeDynamicBindings();
+ }
+
// Each context initializes its own feature info because some extensions may
// be enabled dynamically. Don't disallow any features, leave it up to ANGLE
// to dynamically enable extensions.
@@ -292,6 +634,9 @@ bool GLES2DecoderPassthroughImpl::Initialize(
}
// Check for required extensions
+ // TODO(geofflang): verify
+ // feature_info_->feature_flags().angle_robust_resource_initialization and
+ // glIsEnabled(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
if (!feature_info_->feature_flags().angle_robust_client_memory ||
!feature_info_->feature_flags().chromium_bind_generates_resource ||
!feature_info_->feature_flags().chromium_copy_texture ||
@@ -333,6 +678,9 @@ bool GLES2DecoderPassthroughImpl::Initialize(
feature_info_->feature_flags().nv_egl_stream_consumer_external) {
bound_textures_[GL_TEXTURE_EXTERNAL_OES].resize(num_texture_units);
}
+ if (feature_info_->feature_flags().arb_texture_rectangle) {
+ bound_textures_[GL_TEXTURE_RECTANGLE_ARB].resize(num_texture_units);
+ }
// Initialize the tracked buffer bindings
bound_buffers_[GL_ARRAY_BUFFER] = 0;
@@ -367,6 +715,87 @@ bool GLES2DecoderPassthroughImpl::Initialize(
has_robustness_extension_ = feature_info_->feature_flags().khr_robustness ||
feature_info_->feature_flags().ext_robustness;
+ lose_context_when_out_of_memory_ =
+ attrib_helper.lose_context_when_out_of_memory;
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_2d_texture_size_);
+
+ if (offscreen_) {
+ offscreen_single_buffer_ = attrib_helper.single_buffer;
+ offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved;
+ const bool multisampled_framebuffers_supported =
+ feature_info_->gl_version_info().IsAtLeastGLES(3, 0) ||
+ feature_info_->feature_flags().angle_framebuffer_multisample;
+ if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 &&
+ multisampled_framebuffers_supported && !offscreen_single_buffer_) {
+ GLint max_sample_count = 0;
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
+ emulated_default_framebuffer_format_.samples =
+ std::min(attrib_helper.samples, max_sample_count);
+ }
+
+ const bool rgb8_supported = feature_info_->feature_flags().oes_rgb8_rgba8;
+ const bool alpha_channel_requested = attrib_helper.alpha_size > 0;
+ // The only available default render buffer formats in GLES2 have very
+ // little precision. Don't enable multisampling unless 8-bit render
+ // buffer formats are available--instead fall back to 8-bit textures.
+ if (rgb8_supported && emulated_default_framebuffer_format_.samples > 0) {
+ emulated_default_framebuffer_format_.color_renderbuffer_internal_format =
+ alpha_channel_requested ? GL_RGBA8 : GL_RGB8;
+ } else {
+ emulated_default_framebuffer_format_.samples = 0;
+ }
+
+ emulated_default_framebuffer_format_.color_texture_internal_format =
+ alpha_channel_requested ? GL_RGBA : GL_RGB;
+ emulated_default_framebuffer_format_.color_texture_format =
+ emulated_default_framebuffer_format_.color_texture_internal_format;
+ emulated_default_framebuffer_format_.color_texture_type = GL_UNSIGNED_BYTE;
+
+ const bool depth24_stencil8_supported =
+ feature_info_->feature_flags().packed_depth24_stencil8;
+ if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) &&
+ depth24_stencil8_supported) {
+ emulated_default_framebuffer_format_.depth_stencil_internal_format =
+ GL_DEPTH24_STENCIL8;
+ } else {
+ // It may be the case that this depth/stencil combination is not
+ // supported, but this will be checked later by CheckFramebufferStatus.
+ if (attrib_helper.depth_size > 0) {
+ emulated_default_framebuffer_format_.depth_internal_format =
+ GL_DEPTH_COMPONENT16;
+ }
+ if (attrib_helper.stencil_size > 0) {
+ emulated_default_framebuffer_format_.stencil_internal_format =
+ GL_STENCIL_INDEX8;
+ }
+ }
+
+ FlushErrors();
+ emulated_back_buffer_.reset(new EmulatedDefaultFramebuffer(
+ emulated_default_framebuffer_format_, feature_info_.get()));
+ if (!emulated_back_buffer_->Resize(attrib_helper.offscreen_framebuffer_size,
+ feature_info_.get())) {
+ Destroy(true);
+ return false;
+ }
+
+ if (FlushErrors()) {
+ LOG(ERROR) << "Creation of the offscreen framebuffer failed because "
+ "errors were generated.";
+ Destroy(true);
+ return false;
+ }
+
+ framebuffer_id_map_.SetIDMapping(
+ 0, emulated_back_buffer_->framebuffer_service_id);
+
+ // Bind the emulated default framebuffer and initialize the viewport
+ glBindFramebufferEXT(GL_FRAMEBUFFER,
+ emulated_back_buffer_->framebuffer_service_id);
+ glViewport(0, 0, attrib_helper.offscreen_framebuffer_size.width(),
+ attrib_helper.offscreen_framebuffer_size.height());
+ }
set_initialized();
return true;
@@ -375,6 +804,12 @@ bool GLES2DecoderPassthroughImpl::Initialize(
void GLES2DecoderPassthroughImpl::Destroy(bool have_context) {
if (have_context) {
FlushErrors();
+
+ // Destroy all pending read pixels operations
+ for (const PendingReadPixels& pending_read_pixels : pending_read_pixels_) {
+ glDeleteBuffersARB(1, &pending_read_pixels.buffer_service_id);
+ }
+ pending_read_pixels_.clear();
}
if (!have_context) {
@@ -402,6 +837,27 @@ void GLES2DecoderPassthroughImpl::Destroy(bool have_context) {
glDeleteVertexArraysOES(1, &vertex_array);
});
+ // Destroy the emulated backbuffer
+ if (emulated_back_buffer_) {
+ emulated_back_buffer_->Destroy(have_context);
+ emulated_back_buffer_.reset();
+ }
+
+ if (emulated_front_buffer_) {
+ emulated_front_buffer_->Destroy(have_context);
+ emulated_front_buffer_.reset();
+ }
+
+ for (auto& in_use_color_texture : in_use_color_textures_) {
+ in_use_color_texture->Destroy(have_context);
+ }
+ in_use_color_textures_.clear();
+
+ for (auto& available_color_texture : available_color_textures_) {
+ available_color_texture->Destroy(have_context);
+ }
+ available_color_textures_.clear();
+
// Destroy the GPU Tracer which may own some in process GPU Timings.
if (gpu_tracer_) {
gpu_tracer_->Destroy(have_context);
@@ -448,13 +904,116 @@ void GLES2DecoderPassthroughImpl::ReleaseSurface() {
surface_ = nullptr;
}
-void GLES2DecoderPassthroughImpl::TakeFrontBuffer(const Mailbox& mailbox) {}
+void GLES2DecoderPassthroughImpl::TakeFrontBuffer(const Mailbox& mailbox) {
+ if (offscreen_single_buffer_) {
+ DCHECK(emulated_back_buffer_->color_texture != nullptr);
+ mailbox_manager_->ProduceTexture(
+ mailbox, emulated_back_buffer_->color_texture->texture.get());
+ return;
+ }
+
+ if (!emulated_front_buffer_.get()) {
+ DLOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context";
+ return;
+ }
+
+ mailbox_manager_->ProduceTexture(mailbox,
+ emulated_front_buffer_->texture.get());
+ in_use_color_textures_.push_back(std::move(emulated_front_buffer_));
+ emulated_front_buffer_ = nullptr;
+
+ if (available_color_textures_.empty()) {
+ // Create a new color texture to use as the front buffer
+ emulated_front_buffer_.reset(
+ new EmulatedColorBuffer(emulated_default_framebuffer_format_));
+ if (!emulated_front_buffer_->Resize(emulated_back_buffer_->size)) {
+ DLOG(ERROR) << "Failed to create a new emulated front buffer texture.";
+ return;
+ }
+ create_color_buffer_count_for_test_++;
+ } else {
+ emulated_front_buffer_ = std::move(available_color_textures_.back());
+ available_color_textures_.pop_back();
+ }
+}
void GLES2DecoderPassthroughImpl::ReturnFrontBuffer(const Mailbox& mailbox,
- bool is_lost) {}
+ bool is_lost) {
+ TexturePassthrough* texture = static_cast<TexturePassthrough*>(
+ mailbox_manager_->ConsumeTexture(mailbox));
+
+ if (offscreen_single_buffer_) {
+ return;
+ }
+
+ auto it = in_use_color_textures_.begin();
+ while (it != in_use_color_textures_.end()) {
+ if ((*it)->texture == texture) {
+ break;
+ }
+ it++;
+ }
+ if (it == in_use_color_textures_.end()) {
+ DLOG(ERROR) << "Attempting to return a frontbuffer that was not saved.";
+ return;
+ }
+
+ if (is_lost) {
+ (*it)->texture->MarkContextLost();
+ (*it)->Destroy(false);
+ } else if ((*it)->size != emulated_back_buffer_->size) {
+ (*it)->Destroy(true);
+ } else {
+ available_color_textures_.push_back(std::move(*it));
+ }
+ in_use_color_textures_.erase(it);
+}
bool GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer(
const gfx::Size& size) {
+ DCHECK(offscreen_);
+ if (!emulated_back_buffer_) {
+ LOG(ERROR)
+ << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer called "
+ << " with an onscreen framebuffer.";
+ return false;
+ }
+
+ if (emulated_back_buffer_->size == size) {
+ return true;
+ }
+
+ if (size.width() < 0 || size.height() < 0 ||
+ size.width() > max_2d_texture_size_ ||
+ size.height() > max_2d_texture_size_) {
+ LOG(ERROR) << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer "
+ "failed to allocate storage due to excessive dimensions.";
+ return false;
+ }
+
+ FlushErrors();
+
+ if (!emulated_back_buffer_->Resize(size, feature_info_.get())) {
+ LOG(ERROR) << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer "
+ "failed to resize the emulated framebuffer.";
+ return false;
+ }
+
+ if (FlushErrors()) {
+ LOG(ERROR) << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer "
+ "failed to resize the emulated framebuffer because errors "
+ "were generated.";
+ return false;
+ }
+
+ // Destroy all the available color textures, they should not be the same size
+ // as the back buffer
+ for (auto& available_color_texture : available_color_textures_) {
+ DCHECK(available_color_texture->size != size);
+ available_color_texture->Destroy(true);
+ }
+ available_color_textures_.clear();
+
return true;
}
@@ -573,6 +1132,7 @@ gpu::Capabilities GLES2DecoderPassthroughImpl::GetCapabilities() {
caps.multisample_compatibility =
feature_info_->feature_flags().ext_multisample_compatibility;
caps.dc_layers = !offscreen_ && surface_->SupportsDCLayers();
+ caps.texture_npot = feature_info_->feature_flags().npot_ok;
// TODO:
// caps.commit_overlay_planes
@@ -626,11 +1186,11 @@ void GLES2DecoderPassthroughImpl::SetForceShaderNameHashingForTest(bool force) {
}
size_t GLES2DecoderPassthroughImpl::GetSavedBackTextureCountForTest() {
- return 0;
+ return in_use_color_textures_.size() + available_color_textures_.size();
}
size_t GLES2DecoderPassthroughImpl::GetCreatedBackTextureCountForTest() {
- return 0;
+ return create_color_buffer_count_for_test_;
}
gpu::gles2::QueryManager* GLES2DecoderPassthroughImpl::GetQueryManager() {
@@ -667,11 +1227,14 @@ void GLES2DecoderPassthroughImpl::ProcessPendingQueries(bool did_finish) {
}
bool GLES2DecoderPassthroughImpl::HasMoreIdleWork() const {
- return gpu_tracer_->HasTracesToProcess();
+ return gpu_tracer_->HasTracesToProcess() || !pending_read_pixels_.empty() ||
+ !pending_queries_.empty();
}
void GLES2DecoderPassthroughImpl::PerformIdleWork() {
gpu_tracer_->ProcessTraces();
+ ProcessReadPixels(false);
+ ProcessQueries(false);
}
bool GLES2DecoderPassthroughImpl::HasPollingWork() const {
@@ -1015,6 +1578,14 @@ GLES2DecoderPassthroughImpl::PatchGetFramebufferAttachmentParameter(
}
} break;
+ // If the framebuffer is an emulated default framebuffer, all attachment
+ // object types are GL_FRAMEBUFFER_DEFAULT
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ if (IsEmulatedFramebufferBound(target)) {
+ *params = GL_FRAMEBUFFER_DEFAULT;
+ }
+ break;
+
default:
break;
}
@@ -1038,24 +1609,46 @@ GLenum GLES2DecoderPassthroughImpl::PopError() {
}
bool GLES2DecoderPassthroughImpl::FlushErrors() {
+ auto get_next_error = [this]() {
+ // Always read a real GL error so that it can be replaced by the injected
+ // error
+ GLenum error = glGetError();
+ if (!injected_driver_errors_.empty()) {
+ error = injected_driver_errors_.front();
+ injected_driver_errors_.pop_front();
+ }
+ return error;
+ };
+
bool had_error = false;
- GLenum error = glGetError();
+ GLenum error = get_next_error();
while (error != GL_NO_ERROR) {
errors_.insert(error);
had_error = true;
// Check for context loss on out-of-memory errors
- if (error == GL_OUT_OF_MEMORY && !WasContextLost() && CheckResetStatus()) {
- MarkContextLost(error::kOutOfMemory);
- group_->LoseContexts(error::kUnknown);
+ if (error == GL_OUT_OF_MEMORY && !WasContextLost() &&
+ lose_context_when_out_of_memory_) {
+ error::ContextLostReason other = error::kOutOfMemory;
+ if (CheckResetStatus()) {
+ other = error::kUnknown;
+ } else {
+ // Need to lose current context before broadcasting!
+ MarkContextLost(error::kOutOfMemory);
+ }
+ group_->LoseContexts(other);
break;
}
- error = glGetError();
+ error = get_next_error();
}
return had_error;
}
+void GLES2DecoderPassthroughImpl::InjectDriverError(GLenum error) {
+ injected_driver_errors_.push_back(error);
+}
+
bool GLES2DecoderPassthroughImpl::CheckResetStatus() {
DCHECK(!WasContextLost());
DCHECK(context_->IsCurrent(nullptr));
@@ -1125,9 +1718,20 @@ error::Error GLES2DecoderPassthroughImpl::ProcessQueries(bool did_finish) {
break;
case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
- // TODO: Use a fence and do a real async readback
+ // Initialize the result to being available. Will be marked as
+ // unavailable if any pending read pixels operations reference this
+ // query.
result_available = GL_TRUE;
result = GL_TRUE;
+ for (const PendingReadPixels& pending_read_pixels :
+ pending_read_pixels_) {
+ if (pending_read_pixels.waiting_async_pack_queries.count(
+ query.service_id) > 0) {
+ result_available = GL_FALSE;
+ result = GL_FALSE;
+ break;
+ }
+ }
break;
case GL_GET_ERROR_QUERY_CHROMIUM:
@@ -1188,6 +1792,69 @@ void GLES2DecoderPassthroughImpl::RemovePendingQuery(GLuint service_id) {
}
}
+error::Error GLES2DecoderPassthroughImpl::ProcessReadPixels(bool did_finish) {
+ while (!pending_read_pixels_.empty()) {
+ const PendingReadPixels& pending_read_pixels = pending_read_pixels_.front();
+ if (did_finish || pending_read_pixels.fence->HasCompleted()) {
+ using Result = cmds::ReadPixels::Result;
+ Result* result = nullptr;
+ if (pending_read_pixels.result_shm_id != 0) {
+ result = GetSharedMemoryAs<Result*>(
+ pending_read_pixels.result_shm_id,
+ pending_read_pixels.result_shm_offset, sizeof(*result));
+ if (!result) {
+ glDeleteBuffersARB(1, &pending_read_pixels.buffer_service_id);
+ pending_read_pixels_.pop_front();
+ break;
+ }
+ }
+
+ void* pixels =
+ GetSharedMemoryAs<void*>(pending_read_pixels.pixels_shm_id,
+ pending_read_pixels.pixels_shm_offset,
+ pending_read_pixels.pixels_size);
+ if (!pixels) {
+ glDeleteBuffersARB(1, &pending_read_pixels.buffer_service_id);
+ pending_read_pixels_.pop_front();
+ break;
+ }
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB,
+ pending_read_pixels.buffer_service_id);
+ void* data = nullptr;
+ if (feature_info_->feature_flags().map_buffer_range) {
+ data =
+ glMapBufferRange(GL_PIXEL_PACK_BUFFER_ARB, 0,
+ pending_read_pixels.pixels_size, GL_MAP_READ_BIT);
+ } else {
+ data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ }
+ if (!data) {
+ InsertError(GL_OUT_OF_MEMORY, "Failed to map pixel pack buffer.");
+ pending_read_pixels_.pop_front();
+ break;
+ }
+
+ memcpy(pixels, data, pending_read_pixels.pixels_size);
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB,
+ resources_->buffer_id_map.GetServiceIDOrInvalid(
+ bound_buffers_[GL_PIXEL_PACK_BUFFER_ARB]));
+ glDeleteBuffersARB(1, &pending_read_pixels.buffer_service_id);
+
+ if (result != nullptr) {
+ result->success = 1;
+ }
+
+ pending_read_pixels_.pop_front();
+ }
+ }
+
+ // If glFinish() has been called, all of our fences should be completed.
+ DCHECK(!did_finish || pending_read_pixels_.empty());
+ return error::kNoError;
+}
+
void GLES2DecoderPassthroughImpl::UpdateTextureBinding(
GLenum target,
GLuint client_id,
@@ -1270,6 +1937,24 @@ error::Error GLES2DecoderPassthroughImpl::HandleRasterCHROMIUM(
return error::kNoError;
}
+bool GLES2DecoderPassthroughImpl::IsEmulatedFramebufferBound(
+ GLenum target) const {
+ if (!emulated_back_buffer_) {
+ return false;
+ }
+
+ if ((target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER) &&
+ bound_draw_framebuffer_ == 0) {
+ return true;
+ }
+
+ if (target == GL_READ_FRAMEBUFFER && bound_read_framebuffer_ == 0) {
+ return true;
+ }
+
+ return false;
+}
+
#define GLES2_CMD_OP(name) \
{ \
&GLES2DecoderPassthroughImpl::Handle##name, cmds::name::kArgFlags, \
@@ -1277,7 +1962,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleRasterCHROMIUM(
sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
}, /* NOLINT */
-const GLES2DecoderPassthroughImpl::CommandInfo
+constexpr GLES2DecoderPassthroughImpl::CommandInfo
GLES2DecoderPassthroughImpl::command_info[] = {
GLES2_COMMAND_LIST(GLES2_CMD_OP)};
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index 2d85fa65cc3..8b209280a1e 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -7,6 +7,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_PASSTHROUGH_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_PASSTHROUGH_H_
+#include "base/containers/circular_deque.h"
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/common/debug_marker_manager.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
@@ -22,9 +23,14 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_surface.h"
+namespace gl {
+class GLFence;
+}
+
namespace gpu {
namespace gles2 {
@@ -69,10 +75,39 @@ struct PassthroughResources {
std::unordered_map<GLuint, MappedBuffer> mapped_buffer_map;
};
+class ScopedFramebufferBindingReset {
+ public:
+ ScopedFramebufferBindingReset();
+ ~ScopedFramebufferBindingReset();
+
+ private:
+ GLint draw_framebuffer_;
+ GLint read_framebuffer_;
+};
+
+class ScopedRenderbufferBindingReset {
+ public:
+ ScopedRenderbufferBindingReset();
+ ~ScopedRenderbufferBindingReset();
+
+ private:
+ GLint renderbuffer_;
+};
+
+class ScopedTexture2DBindingReset {
+ public:
+ ScopedTexture2DBindingReset();
+ ~ScopedTexture2DBindingReset();
+
+ private:
+ GLint texture_;
+};
+
class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
public:
GLES2DecoderPassthroughImpl(GLES2DecoderClient* client,
CommandBufferServiceBase* command_buffer_service,
+ Outputter* outputter,
ContextGroup* group);
~GLES2DecoderPassthroughImpl() override;
@@ -254,6 +289,9 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
bool can_bind_to_sampler) override;
private:
+ // Allow unittests to inspect internal state tracking
+ friend class GLES2DecoderPassthroughTestBase;
+
const char* GetCommandName(unsigned int command_id) const;
void* GetScratchMemory(size_t size);
@@ -306,6 +344,10 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
GLenum PopError();
bool FlushErrors();
+ // Inject a driver-level GL error that will replace the result of the next
+ // call to glGetError
+ void InjectDriverError(GLenum error);
+
bool CheckResetStatus();
bool IsRobustnessSupported();
@@ -313,6 +355,8 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
error::Error ProcessQueries(bool did_finish);
void RemovePendingQuery(GLuint service_id);
+ error::Error ProcessReadPixels(bool did_finish);
+
void UpdateTextureBinding(GLenum target,
GLuint client_id,
TexturePassthrough* texture);
@@ -323,6 +367,8 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
void VerifyServiceTextureObjectsExist();
+ bool IsEmulatedFramebufferBound(GLenum target) const;
+
GLES2DecoderClient* client_;
int commands_to_process_;
@@ -418,7 +464,7 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
QuerySync* sync = nullptr;
base::subtle::Atomic32 submit_count = 0;
};
- std::deque<PendingQuery> pending_queries_;
+ base::circular_deque<PendingQuery> pending_queries_;
// Currently active queries
struct ActiveQuery {
@@ -435,8 +481,116 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
};
std::unordered_map<GLenum, ActiveQuery> active_queries_;
+ // Pending async ReadPixels calls
+ struct PendingReadPixels {
+ PendingReadPixels();
+ ~PendingReadPixels();
+ PendingReadPixels(PendingReadPixels&&);
+ PendingReadPixels& operator=(PendingReadPixels&&);
+
+ std::unique_ptr<gl::GLFence> fence = nullptr;
+ GLuint buffer_service_id = 0;
+ uint32_t pixels_size = 0;
+ uint32_t pixels_shm_id = 0;
+ uint32_t pixels_shm_offset = 0;
+ uint32_t result_shm_id = 0;
+ uint32_t result_shm_offset = 0;
+
+ // Service IDs of GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM queries waiting for
+ // this read pixels operation to complete
+ base::flat_set<GLuint> waiting_async_pack_queries;
+
+ DISALLOW_COPY_AND_ASSIGN(PendingReadPixels);
+ };
+ base::circular_deque<PendingReadPixels> pending_read_pixels_;
+
+ // Error state
+ base::circular_deque<GLenum> injected_driver_errors_;
std::set<GLenum> errors_;
+ // Default framebuffer emulation
+ struct EmulatedDefaultFramebufferFormat {
+ GLenum color_renderbuffer_internal_format = GL_NONE;
+ GLenum color_texture_internal_format = GL_NONE;
+ GLenum color_texture_format = GL_NONE;
+ GLenum color_texture_type = GL_NONE;
+ GLenum depth_stencil_internal_format = GL_NONE;
+ GLenum depth_internal_format = GL_NONE;
+ GLenum stencil_internal_format = GL_NONE;
+ GLint samples = 0;
+ };
+
+ struct EmulatedColorBuffer {
+ explicit EmulatedColorBuffer(
+ const EmulatedDefaultFramebufferFormat& format_in);
+ ~EmulatedColorBuffer();
+
+ bool Resize(const gfx::Size& new_size);
+ void Destroy(bool have_context);
+
+ scoped_refptr<TexturePassthrough> texture;
+
+ gfx::Size size;
+ EmulatedDefaultFramebufferFormat format;
+
+ DISALLOW_COPY_AND_ASSIGN(EmulatedColorBuffer);
+ };
+
+ struct EmulatedDefaultFramebuffer {
+ EmulatedDefaultFramebuffer(
+ const EmulatedDefaultFramebufferFormat& format_in,
+ const FeatureInfo* feature_info);
+ ~EmulatedDefaultFramebuffer();
+
+ // Set a new color buffer, return the old one
+ std::unique_ptr<EmulatedColorBuffer> SetColorBuffer(
+ std::unique_ptr<EmulatedColorBuffer> new_color_buffer);
+
+ // Blit this framebuffer into another same-sized color buffer
+ void Blit(EmulatedColorBuffer* target);
+
+ bool Resize(const gfx::Size& new_size, const FeatureInfo* feature_info);
+ void Destroy(bool have_context);
+
+ // Service ID of the framebuffer
+ GLuint framebuffer_service_id = 0;
+
+ // Service ID of the color renderbuffer (if multisampled)
+ GLuint color_buffer_service_id = 0;
+
+ // Color buffer texture (if not multisampled)
+ std::unique_ptr<EmulatedColorBuffer> color_texture;
+
+ // Service ID of the depth stencil renderbuffer
+ GLuint depth_stencil_buffer_service_id = 0;
+
+ // Service ID of the depth renderbuffer
+ GLuint depth_buffer_service_id = 0;
+
+ // Service ID of the stencil renderbuffer (
+ GLuint stencil_buffer_service_id = 0;
+
+ gfx::Size size;
+ EmulatedDefaultFramebufferFormat format;
+
+ DISALLOW_COPY_AND_ASSIGN(EmulatedDefaultFramebuffer);
+ };
+ EmulatedDefaultFramebufferFormat emulated_default_framebuffer_format_;
+ std::unique_ptr<EmulatedDefaultFramebuffer> emulated_back_buffer_;
+ std::unique_ptr<EmulatedColorBuffer> emulated_front_buffer_;
+ bool offscreen_single_buffer_;
+ bool offscreen_target_buffer_preserved_;
+ std::vector<std::unique_ptr<EmulatedColorBuffer>> in_use_color_textures_;
+ std::vector<std::unique_ptr<EmulatedColorBuffer>> available_color_textures_;
+ size_t create_color_buffer_count_for_test_;
+
+ // Maximum 2D texture size for limiting offscreen framebuffer sizes
+ GLint max_2d_texture_size_;
+
+ // State tracking of currently bound draw and read framebuffers (client IDs)
+ GLuint bound_draw_framebuffer_;
+ GLuint bound_read_framebuffer_;
+
// Tracing
std::unique_ptr<GPUTracer> gpu_tracer_;
const unsigned char* gpu_decoder_category_;
@@ -448,6 +602,7 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
bool has_robustness_extension_;
bool context_lost_;
bool reset_by_robustness_extension_;
+ bool lose_context_when_out_of_memory_;
// Cache of scratch memory
std::vector<uint8_t> scratch_memory_;
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
index a598f9027de..55c292e2073 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -428,6 +428,20 @@ error::Error DoReadPixels(GLint x,
GLsizei* rows,
void* pixels,
int32_t* success);
+error::Error DoReadPixelsAsync(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufsize,
+ GLsizei* length,
+ GLsizei* columns,
+ GLsizei* rows,
+ uint32_t pixels_shm_id,
+ uint32_t pixels_shm_offset,
+ uint32_t result_shm_id,
+ uint32_t result_shm_offset);
error::Error DoReleaseShaderCompiler();
error::Error DoRenderbufferStorage(GLenum target,
GLenum internalformat,
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index e08bc9719c5..8b6433b39e9 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -61,8 +61,13 @@ error::Error DeleteHelper(GLsizei n,
std::vector<ServiceType> service_ids(n, 0);
for (GLsizei ii = 0; ii < n; ++ii) {
ClientType client_id = client_ids[ii];
- service_ids[ii] = id_map->GetServiceIDOrInvalid(client_id);
- id_map->RemoveClientID(client_id);
+
+ // Don't pass service IDs of objects with a client ID of 0. They are
+ // emulated and should not be deleteable
+ if (client_id != 0) {
+ service_ids[ii] = id_map->GetServiceIDOrInvalid(client_id);
+ id_map->RemoveClientID(client_id);
+ }
}
delete_function(n, service_ids.data());
@@ -273,6 +278,35 @@ class ScopedPackStateRowLengthReset {
GLint row_length_ = 0;
};
+bool ModifyAttachmentForEmulatedFramebuffer(GLenum* attachment) {
+ switch (*attachment) {
+ case GL_BACK:
+ *attachment = GL_COLOR_ATTACHMENT0;
+ return true;
+
+ case GL_DEPTH:
+ *attachment = GL_DEPTH_ATTACHMENT;
+ return true;
+
+ case GL_STENCIL:
+ *attachment = GL_STENCIL_ATTACHMENT;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ModifyAttachmentsForEmulatedFramebuffer(std::vector<GLenum>* attachments) {
+ for (GLenum& attachment : *attachments) {
+ if (!ModifyAttachmentForEmulatedFramebuffer(&attachment)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // anonymous namespace
// Implementations of commands
@@ -357,9 +391,34 @@ error::Error GLES2DecoderPassthroughImpl::DoBindBufferRange(GLenum target,
error::Error GLES2DecoderPassthroughImpl::DoBindFramebuffer(
GLenum target,
GLuint framebuffer) {
+ FlushErrors();
glBindFramebufferEXT(
target, GetFramebufferServiceID(framebuffer, &framebuffer_id_map_,
bind_generates_resource_));
+ if (FlushErrors()) {
+ return error::kNoError;
+ }
+
+ // Update tracking of the bound framebuffer
+ switch (target) {
+ case GL_FRAMEBUFFER_EXT:
+ bound_draw_framebuffer_ = framebuffer;
+ bound_read_framebuffer_ = framebuffer;
+ break;
+
+ case GL_DRAW_FRAMEBUFFER:
+ bound_draw_framebuffer_ = framebuffer;
+ break;
+
+ case GL_READ_FRAMEBUFFER:
+ bound_read_framebuffer_ = framebuffer;
+ break;
+
+ default:
+ NOTREACHED();
+ break;
+ }
+
return error::kNoError;
}
@@ -746,7 +805,29 @@ error::Error GLES2DecoderPassthroughImpl::DoDeleteFramebuffers(
InsertError(GL_INVALID_VALUE, "n cannot be negative.");
return error::kNoError;
}
- return DeleteHelper(n, framebuffers, &framebuffer_id_map_,
+
+ std::vector<GLuint> framebuffers_copy(framebuffers, framebuffers + n);
+
+ // If a bound framebuffer is deleted, it's binding is reset to 0. In the case
+ // of an emulated default framebuffer, bind the emulated one.
+ for (GLuint framebuffer : framebuffers_copy) {
+ if (framebuffer == bound_draw_framebuffer_) {
+ bound_draw_framebuffer_ = 0;
+ if (emulated_back_buffer_) {
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER,
+ emulated_back_buffer_->framebuffer_service_id);
+ }
+ }
+ if (framebuffer == bound_read_framebuffer_) {
+ bound_read_framebuffer_ = 0;
+ if (emulated_back_buffer_) {
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER,
+ emulated_back_buffer_->framebuffer_service_id);
+ }
+ }
+ }
+
+ return DeleteHelper(n, framebuffers_copy.data(), &framebuffer_id_map_,
[](GLsizei n, GLuint* framebuffers) {
glDeleteFramebuffersEXT(n, framebuffers);
});
@@ -927,11 +1008,21 @@ error::Error GLES2DecoderPassthroughImpl::DoFenceSync(GLenum condition,
error::Error GLES2DecoderPassthroughImpl::DoFinish() {
glFinish();
+
+ error::Error error = ProcessReadPixels(true);
+ if (error != error::kNoError) {
+ return error;
+ }
return ProcessQueries(true);
}
error::Error GLES2DecoderPassthroughImpl::DoFlush() {
glFlush();
+
+ error::Error error = ProcessReadPixels(false);
+ if (error != error::kNoError) {
+ return error;
+ }
return ProcessQueries(false);
}
@@ -991,6 +1082,11 @@ error::Error GLES2DecoderPassthroughImpl::DoFramebufferRenderbuffer(
GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer) {
+ if (IsEmulatedFramebufferBound(target)) {
+ InsertError(GL_INVALID_OPERATION,
+ "Cannot change the attachments of the default framebuffer.");
+ return error::kNoError;
+ }
glFramebufferRenderbufferEXT(
target, attachment, renderbuffertarget,
GetRenderbufferServiceID(renderbuffer, resources_, false));
@@ -1003,6 +1099,11 @@ error::Error GLES2DecoderPassthroughImpl::DoFramebufferTexture2D(
GLenum textarget,
GLuint texture,
GLint level) {
+ if (IsEmulatedFramebufferBound(target)) {
+ InsertError(GL_INVALID_OPERATION,
+ "Cannot change the attachments of the default framebuffer.");
+ return error::kNoError;
+ }
glFramebufferTexture2DEXT(target, attachment, textarget,
GetTextureServiceID(texture, resources_, false),
level);
@@ -1015,6 +1116,11 @@ error::Error GLES2DecoderPassthroughImpl::DoFramebufferTextureLayer(
GLuint texture,
GLint level,
GLint layer) {
+ if (IsEmulatedFramebufferBound(target)) {
+ InsertError(GL_INVALID_OPERATION,
+ "Cannot change the attachments of the default framebuffer.");
+ return error::kNoError;
+ }
glFramebufferTextureLayer(target, attachment,
GetTextureServiceID(texture, resources_, false),
level, layer);
@@ -1290,14 +1396,43 @@ error::Error GLES2DecoderPassthroughImpl::DoGetFramebufferAttachmentParameteriv(
GLsizei bufsize,
GLsizei* length,
GLint* params) {
+ GLenum updated_attachment = attachment;
+ if (IsEmulatedFramebufferBound(target)) {
+ // Update the attachment do the equivalent one in the emulated framebuffer
+ if (!ModifyAttachmentForEmulatedFramebuffer(&updated_attachment)) {
+ InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
+ *length = 0;
+ return error::kNoError;
+ }
+
+ // Generate errors for parameter names that are only valid for non-default
+ // framebuffers
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ InsertError(GL_INVALID_ENUM, "Invalid parameter name.");
+ *length = 0;
+ return error::kNoError;
+ }
+ }
+
+ FlushErrors();
+
// Get a scratch buffer to hold the result of the query
GLint* scratch_params = GetTypedScratchMemory<GLint>(bufsize);
glGetFramebufferAttachmentParameterivRobustANGLE(
- target, attachment, pname, bufsize, length, scratch_params);
+ target, updated_attachment, pname, bufsize, length, scratch_params);
+
+ if (FlushErrors()) {
+ DCHECK(*length == 0);
+ return error::kNoError;
+ }
// Update the results of the query, if needed
error::Error error = PatchGetFramebufferAttachmentParameter(
- target, attachment, pname, *length, scratch_params);
+ target, updated_attachment, pname, *length, scratch_params);
if (error != error::kNoError) {
*length = 0;
return error;
@@ -1702,7 +1837,15 @@ error::Error GLES2DecoderPassthroughImpl::DoInvalidateFramebuffer(
InsertError(GL_INVALID_VALUE, "count cannot be negative.");
return error::kNoError;
}
+
std::vector<GLenum> attachments_copy(attachments, attachments + count);
+ if (IsEmulatedFramebufferBound(target)) {
+ // Update the attachment do the equivalent one in the emulated framebuffer
+ if (!ModifyAttachmentsForEmulatedFramebuffer(&attachments_copy)) {
+ InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
+ return error::kNoError;
+ }
+ }
glInvalidateFramebuffer(target, count, attachments_copy.data());
return error::kNoError;
}
@@ -1720,7 +1863,15 @@ error::Error GLES2DecoderPassthroughImpl::DoInvalidateSubFramebuffer(
InsertError(GL_INVALID_VALUE, "count cannot be negative.");
return error::kNoError;
}
+
std::vector<GLenum> attachments_copy(attachments, attachments + count);
+ if (IsEmulatedFramebufferBound(target)) {
+ // Update the attachment do the equivalent one in the emulated framebuffer
+ if (!ModifyAttachmentsForEmulatedFramebuffer(&attachments_copy)) {
+ InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
+ return error::kNoError;
+ }
+ }
glInvalidateSubFramebuffer(target, count, attachments_copy.data(), x, y,
width, height);
return error::kNoError;
@@ -1843,6 +1994,84 @@ error::Error GLES2DecoderPassthroughImpl::DoReadPixels(GLint x,
return error::kNoError;
}
+error::Error GLES2DecoderPassthroughImpl::DoReadPixelsAsync(
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufsize,
+ GLsizei* length,
+ GLsizei* columns,
+ GLsizei* rows,
+ uint32_t pixels_shm_id,
+ uint32_t pixels_shm_offset,
+ uint32_t result_shm_id,
+ uint32_t result_shm_offset) {
+ DCHECK(feature_info_->feature_flags().use_async_readpixels &&
+ bound_buffers_[GL_PIXEL_PACK_BUFFER] == 0);
+
+ FlushErrors();
+ ScopedPackStateRowLengthReset reset_row_length(
+ bufsize != 0 && feature_info_->gl_version_info().is_es3);
+
+ PendingReadPixels pending_read_pixels;
+ pending_read_pixels.pixels_shm_id = pixels_shm_id;
+ pending_read_pixels.pixels_shm_offset = pixels_shm_offset;
+ pending_read_pixels.result_shm_id = result_shm_id;
+ pending_read_pixels.result_shm_offset = result_shm_offset;
+
+ glGenBuffersARB(1, &pending_read_pixels.buffer_service_id);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pending_read_pixels.buffer_service_id);
+
+ // GL_STREAM_READ is not available until ES3.
+ const GLenum usage_hint = feature_info_->gl_version_info().IsAtLeastGLES(3, 0)
+ ? GL_STREAM_READ
+ : GL_STATIC_DRAW;
+
+ const uint32_t bytes_per_pixel =
+ GLES2Util::ComputeImageGroupSize(format, type);
+ if (bytes_per_pixel == 0) {
+ InsertError(GL_INVALID_ENUM, "Invalid ReadPixels format or type.");
+ return error::kNoError;
+ }
+
+ if (width < 0 || height < 0) {
+ InsertError(GL_INVALID_VALUE, "Width and height cannot be negative.");
+ return error::kNoError;
+ }
+
+ if (!base::CheckMul(bytes_per_pixel, width, height)
+ .AssignIfValid(&pending_read_pixels.pixels_size)) {
+ return error::kOutOfBounds;
+ }
+
+ glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pending_read_pixels.pixels_size,
+ nullptr, usage_hint);
+
+ // No need to worry about ES3 pixel pack parameters, because no
+ // PIXEL_PACK_BUFFER is bound, and all these settings haven't been
+ // sent to GL.
+ glReadPixels(x, y, width, height, format, type, nullptr);
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+ // Test for errors now before creating a fence
+ if (FlushErrors()) {
+ return error::kNoError;
+ }
+
+ pending_read_pixels.fence.reset(gl::GLFence::Create());
+
+ if (FlushErrors()) {
+ return error::kNoError;
+ }
+
+ pending_read_pixels_.push_back(std::move(pending_read_pixels));
+ return error::kNoError;
+}
+
error::Error GLES2DecoderPassthroughImpl::DoReleaseShaderCompiler() {
glReleaseShaderCompiler();
return error::kNoError;
@@ -2591,6 +2820,11 @@ error::Error GLES2DecoderPassthroughImpl::DoFramebufferTexture2DMultisampleEXT(
return error::kUnknownCommand;
}
+ if (IsEmulatedFramebufferBound(target)) {
+ InsertError(GL_INVALID_OPERATION,
+ "Cannot change the attachments of the default framebuffer.");
+ return error::kNoError;
+ }
glFramebufferTexture2DMultisampleEXT(
target, attachment, textarget,
GetTextureServiceID(texture, resources_, false), level, samples);
@@ -2769,10 +3003,17 @@ error::Error GLES2DecoderPassthroughImpl::DoBeginTransformFeedback(
error::Error GLES2DecoderPassthroughImpl::DoEndQueryEXT(GLenum target,
uint32_t submit_count) {
if (IsEmulatedQueryTarget(target)) {
- if (active_queries_.find(target) == active_queries_.end()) {
+ auto active_query_iter = active_queries_.find(target);
+ if (active_query_iter == active_queries_.end()) {
InsertError(GL_INVALID_OPERATION, "No active query on target.");
return error::kNoError;
}
+ if (target == GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM &&
+ !pending_read_pixels_.empty()) {
+ GLuint query_service_id = active_query_iter->second.service_id;
+ pending_read_pixels_.back().waiting_async_pack_queries.insert(
+ query_service_id);
+ }
} else {
// Flush all previous errors
FlushErrors();
@@ -2872,7 +3113,55 @@ error::Error GLES2DecoderPassthroughImpl::DoBindVertexArrayOES(GLuint array) {
error::Error GLES2DecoderPassthroughImpl::DoSwapBuffers() {
if (offscreen_) {
- NOTIMPLEMENTED();
+ if (offscreen_single_buffer_) {
+ return error::kNoError;
+ }
+
+ DCHECK(emulated_back_buffer_);
+
+ // Make sure the emulated front buffer is allocated and the correct size
+ if (emulated_front_buffer_ &&
+ emulated_front_buffer_->size != emulated_back_buffer_->size) {
+ emulated_front_buffer_->Destroy(true);
+ emulated_front_buffer_ = nullptr;
+ }
+
+ if (emulated_front_buffer_ == nullptr) {
+ if (!available_color_textures_.empty()) {
+ emulated_front_buffer_ = std::move(available_color_textures_.back());
+ available_color_textures_.pop_back();
+ } else {
+ emulated_front_buffer_.reset(
+ new EmulatedColorBuffer(emulated_default_framebuffer_format_));
+ if (!emulated_front_buffer_->Resize(emulated_back_buffer_->size)) {
+ DLOG(ERROR)
+ << "Failed to create a new emulated front buffer texture.";
+ return error::kLostContext;
+ }
+ }
+ }
+
+ DCHECK(emulated_front_buffer_->size == emulated_back_buffer_->size);
+
+ if (emulated_default_framebuffer_format_.samples > 0) {
+ // Resolve the multisampled renderbuffer into the emulated_front_buffer_
+ emulated_back_buffer_->Blit(emulated_front_buffer_.get());
+ } else {
+ DCHECK(emulated_back_buffer_->color_texture != nullptr);
+ // If the offscreen buffer should be preserved, copy the old backbuffer
+ // into the new one
+ if (offscreen_target_buffer_preserved_) {
+ emulated_back_buffer_->Blit(emulated_front_buffer_.get());
+ }
+
+ // Swap the front and back buffer textures and update the framebuffer
+ // attachment.
+ std::unique_ptr<EmulatedColorBuffer> old_front_buffer =
+ std::move(emulated_front_buffer_);
+ emulated_front_buffer_ =
+ emulated_back_buffer_->SetColorBuffer(std::move(old_front_buffer));
+ }
+
return error::kNoError;
}
@@ -3012,30 +3301,33 @@ error::Error GLES2DecoderPassthroughImpl::DoResizeCHROMIUM(GLuint width,
GLfloat scale_factor,
GLenum color_space,
GLboolean alpha) {
- gl::GLSurface::ColorSpace surface_color_space =
- gl::GLSurface::ColorSpace::UNSPECIFIED;
- switch (color_space) {
- case GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM:
- surface_color_space = gl::GLSurface::ColorSpace::UNSPECIFIED;
- break;
- case GL_COLOR_SPACE_SCRGB_LINEAR_CHROMIUM:
- surface_color_space = gl::GLSurface::ColorSpace::SCRGB_LINEAR;
- break;
- case GL_COLOR_SPACE_SRGB_CHROMIUM:
- surface_color_space = gl::GLSurface::ColorSpace::SRGB;
- break;
- case GL_COLOR_SPACE_DISPLAY_P3_CHROMIUM:
- surface_color_space = gl::GLSurface::ColorSpace::DISPLAY_P3;
- break;
- default:
+ if (offscreen_) {
+ if (!ResizeOffscreenFramebuffer(gfx::Size(width, height))) {
LOG(ERROR) << "GLES2DecoderPassthroughImpl: Context lost because "
- "specified color space was invalid.";
+ << "ResizeOffscreenFramebuffer failed.";
return error::kLostContext;
- }
- if (offscreen_) {
- // TODO: crbug.com/665521
- NOTIMPLEMENTED();
+ }
} else {
+ gl::GLSurface::ColorSpace surface_color_space =
+ gl::GLSurface::ColorSpace::UNSPECIFIED;
+ switch (color_space) {
+ case GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM:
+ surface_color_space = gl::GLSurface::ColorSpace::UNSPECIFIED;
+ break;
+ case GL_COLOR_SPACE_SCRGB_LINEAR_CHROMIUM:
+ surface_color_space = gl::GLSurface::ColorSpace::SCRGB_LINEAR;
+ break;
+ case GL_COLOR_SPACE_SRGB_CHROMIUM:
+ surface_color_space = gl::GLSurface::ColorSpace::SRGB;
+ break;
+ case GL_COLOR_SPACE_DISPLAY_P3_CHROMIUM:
+ surface_color_space = gl::GLSurface::ColorSpace::DISPLAY_P3;
+ break;
+ default:
+ LOG(ERROR) << "GLES2DecoderPassthroughImpl: Context lost because "
+ "specified color space was invalid.";
+ return error::kLostContext;
+ }
if (!surface_->Resize(gfx::Size(width, height), scale_factor,
surface_color_space, !!alpha)) {
LOG(ERROR)
@@ -3542,6 +3834,9 @@ error::Error GLES2DecoderPassthroughImpl::DoDrawArraysInstancedANGLE(
GLint first,
GLsizei count,
GLsizei primcount) {
+ if (!feature_info_->feature_flags().angle_instanced_arrays) {
+ return error::kUnknownCommand;
+ }
glDrawArraysInstancedANGLE(mode, first, count, primcount);
return error::kNoError;
}
@@ -3552,6 +3847,9 @@ error::Error GLES2DecoderPassthroughImpl::DoDrawElementsInstancedANGLE(
GLenum type,
const void* indices,
GLsizei primcount) {
+ if (!feature_info_->feature_flags().angle_instanced_arrays) {
+ return error::kUnknownCommand;
+ }
glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
return error::kNoError;
}
@@ -3559,6 +3857,9 @@ error::Error GLES2DecoderPassthroughImpl::DoDrawElementsInstancedANGLE(
error::Error GLES2DecoderPassthroughImpl::DoVertexAttribDivisorANGLE(
GLuint index,
GLuint divisor) {
+ if (!feature_info_->feature_flags().angle_instanced_arrays) {
+ return error::kUnknownCommand;
+ }
glVertexAttribDivisorANGLE(index, divisor);
return error::kNoError;
}
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
index 75e33d2b5d4..20b117d3b48 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
@@ -16,7 +16,9 @@ error::Error GLES2DecoderPassthroughImpl::HandleBindAttribLocationBucket(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLuint index = static_cast<GLuint>(c.index);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -24,11 +26,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleBindAttribLocationBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- error::Error error = DoBindAttribLocation(program, index, name_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBindAttribLocation(program, index, name_str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleBufferData(
@@ -38,21 +36,18 @@ error::Error GLES2DecoderPassthroughImpl::HandleBufferData(
*static_cast<const volatile gles2::cmds::BufferData*>(cmd_data);
GLenum target = static_cast<GLenum>(c.target);
GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
- uint32_t data_shm_id = static_cast<uint32_t>(c.data_shm_id);
- uint32_t data_shm_offset = static_cast<uint32_t>(c.data_shm_offset);
+ uint32_t data_shm_id = c.data_shm_id;
+ uint32_t data_shm_offset = c.data_shm_offset;
GLenum usage = static_cast<GLenum>(c.usage);
- const void* data = NULL;
+
+ const void* data = nullptr;
if (data_shm_id != 0 || data_shm_offset != 0) {
data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
if (!data) {
return error::kOutOfBounds;
}
}
- error::Error error = DoBufferData(target, size, data, usage);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBufferData(target, size, data, usage);
}
error::Error GLES2DecoderPassthroughImpl::HandleClientWaitSync(
@@ -63,17 +58,16 @@ error::Error GLES2DecoderPassthroughImpl::HandleClientWaitSync(
const GLuint sync = static_cast<GLuint>(c.sync);
const GLbitfield flags = static_cast<GLbitfield>(c.flags);
const GLuint64 timeout = c.timeout();
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::ClientWaitSync::Result Result;
Result* result_dst = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ result_shm_id, result_shm_offset, sizeof(*result_dst));
if (!result_dst) {
return error::kOutOfBounds;
}
- error::Error error = DoClientWaitSync(sync, flags, timeout, result_dst);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoClientWaitSync(sync, flags, timeout, result_dst);
}
error::Error GLES2DecoderPassthroughImpl::HandleCreateProgram(
@@ -82,11 +76,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleCreateProgram(
const volatile gles2::cmds::CreateProgram& c =
*static_cast<const volatile gles2::cmds::CreateProgram*>(cmd_data);
GLuint client_id = static_cast<GLuint>(c.client_id);
- error::Error error = DoCreateProgram(client_id);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoCreateProgram(client_id);
}
error::Error GLES2DecoderPassthroughImpl::HandleCreateShader(
@@ -96,11 +87,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleCreateShader(
*static_cast<const volatile gles2::cmds::CreateShader*>(cmd_data);
GLenum type = static_cast<GLenum>(c.type);
GLuint client_id = static_cast<GLuint>(c.client_id);
- error::Error error = DoCreateShader(type, client_id);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoCreateShader(type, client_id);
}
error::Error GLES2DecoderPassthroughImpl::HandleFenceSync(
@@ -111,11 +99,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleFenceSync(
GLenum condition = static_cast<GLenum>(c.condition);
GLbitfield flags = static_cast<GLbitfield>(c.flags);
GLuint client_id = static_cast<GLuint>(c.client_id);
- error::Error error = DoFenceSync(condition, flags, client_id);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoFenceSync(condition, flags, client_id);
}
error::Error GLES2DecoderPassthroughImpl::HandleDrawArrays(
@@ -126,11 +111,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleDrawArrays(
GLenum mode = static_cast<GLenum>(c.mode);
GLint first = static_cast<GLint>(c.first);
GLsizei count = static_cast<GLsizei>(c.count);
- error::Error error = DoDrawArrays(mode, first, count);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoDrawArrays(mode, first, count);
}
error::Error GLES2DecoderPassthroughImpl::HandleDrawElements(
@@ -143,11 +125,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleDrawElements(
GLenum type = static_cast<GLenum>(c.type);
const GLvoid* indices =
reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(c.index_offset));
- error::Error error = DoDrawElements(mode, count, type, indices);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoDrawElements(mode, count, type, indices);
}
error::Error GLES2DecoderPassthroughImpl::HandleGetActiveAttrib(
@@ -158,9 +137,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveAttrib(
GLuint program = static_cast<GLuint>(c.program);
GLuint index = static_cast<GLuint>(c.index);
uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetActiveAttrib::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -190,9 +172,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveUniform(
GLuint program = static_cast<GLuint>(c.program);
GLuint index = static_cast<GLuint>(c.index);
uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetActiveUniform::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -223,12 +208,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveUniformBlockiv(
GLuint program = static_cast<GLuint>(c.program);
GLuint uniformBlockIndex = static_cast<GLuint>(c.index);
GLenum pname = static_cast<GLenum>(c.pname);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetActiveUniformBlockiv::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size);
- GLint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, sizeof(Result), &buffer_size);
+ GLint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -254,9 +242,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveUniformBlockName(
GLuint program = static_cast<GLuint>(c.program);
GLuint uniformBlockIndex = static_cast<GLuint>(c.index);
uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetActiveUniformBlockName::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -285,7 +276,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveUniformsiv(
*static_cast<const volatile gles2::cmds::GetActiveUniformsiv*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLenum pname = static_cast<GLenum>(c.pname);
- Bucket* bucket = GetBucket(c.indices_bucket_id);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+ uint32_t indices_bucket_id = c.indices_bucket_id;
+
+ Bucket* bucket = GetBucket(indices_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -293,9 +288,9 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetActiveUniformsiv(
const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
typedef cmds::GetActiveUniformsiv::Result Result;
Result* result = GetSharedMemoryAs<Result*>(
- c.params_shm_id, c.params_shm_offset, Result::ComputeSize(uniformCount));
- GLint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, Result::ComputeSize(uniformCount));
+ GLint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
// Check that the client initialized the result.
@@ -319,10 +314,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetAttachedShaders(
const volatile gles2::cmds::GetAttachedShaders& c =
*static_cast<const volatile gles2::cmds::GetAttachedShaders*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
+ uint32_t result_size = c.result_size;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetAttachedShaders::Result Result;
- uint32_t maxCount = Result::ComputeMaxResults(c.result_size);
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, Result::ComputeSize(maxCount));
+ uint32_t maxCount = Result::ComputeMaxResults(result_size);
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ Result::ComputeSize(maxCount));
if (!result) {
return error::kOutOfBounds;
}
@@ -347,7 +346,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetAttribLocation(
const volatile gles2::cmds::GetAttribLocation& c =
*static_cast<const volatile gles2::cmds::GetAttribLocation*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t location_shm_id = c.location_shm_id;
+ uint32_t location_shm_offset = c.location_shm_offset;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -356,18 +359,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetAttribLocation(
return error::kInvalidArguments;
}
GLint* location = GetSharedMemoryAs<GLint*>(
- c.location_shm_id, c.location_shm_offset, sizeof(GLint));
+ location_shm_id, location_shm_offset, sizeof(GLint));
if (!location) {
return error::kOutOfBounds;
}
if (*location != -1) {
return error::kInvalidArguments;
}
- error::Error error = DoGetAttribLocation(program, name_str.c_str(), location);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoGetAttribLocation(program, name_str.c_str(), location);
}
error::Error GLES2DecoderPassthroughImpl::HandleGetBufferSubDataAsyncCHROMIUM(
@@ -379,21 +378,16 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetBufferSubDataAsyncCHROMIUM(
GLenum target = static_cast<GLenum>(c.target);
GLintptr offset = static_cast<GLintptr>(c.offset);
GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
- uint32_t data_shm_id = static_cast<uint32_t>(c.data_shm_id);
+ uint32_t data_shm_id = c.data_shm_id;
+ uint32_t data_shm_offset = c.data_shm_offset;
uint8_t* mem =
- GetSharedMemoryAs<uint8_t*>(data_shm_id, c.data_shm_offset, size);
+ GetSharedMemoryAs<uint8_t*>(data_shm_id, data_shm_offset, size);
if (!mem) {
return error::kOutOfBounds;
}
- error::Error error =
- DoGetBufferSubDataAsyncCHROMIUM(target, offset, size, mem);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoGetBufferSubDataAsyncCHROMIUM(target, offset, size, mem);
}
@@ -403,7 +397,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataLocation(
const volatile gles2::cmds::GetFragDataLocation& c =
*static_cast<const volatile gles2::cmds::GetFragDataLocation*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t location_shm_id = c.location_shm_id;
+ uint32_t location_shm_offset = c.location_shm_offset;
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -412,19 +410,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataLocation(
return error::kInvalidArguments;
}
GLint* location = GetSharedMemoryAs<GLint*>(
- c.location_shm_id, c.location_shm_offset, sizeof(GLint));
+ location_shm_id, location_shm_offset, sizeof(GLint));
if (!location) {
return error::kOutOfBounds;
}
if (*location != -1) {
return error::kInvalidArguments;
}
- error::Error error =
- DoGetFragDataLocation(program, name_str.c_str(), location);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoGetFragDataLocation(program, name_str.c_str(), location);
}
error::Error GLES2DecoderPassthroughImpl::HandleGetInternalformativ(
@@ -435,12 +428,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetInternalformativ(
GLenum target = static_cast<GLenum>(c.target);
GLenum internalformat = static_cast<GLenum>(c.format);
GLenum pname = static_cast<GLenum>(c.pname);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetInternalformativ::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size);
- GLint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, sizeof(Result), &buffer_size);
+ GLint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -463,7 +459,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetProgramInfoLog(
const volatile gles2::cmds::GetProgramInfoLog& c =
*static_cast<const volatile gles2::cmds::GetProgramInfoLog*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
std::string infolog;
error::Error error = DoGetProgramInfoLog(program, &infolog);
@@ -482,7 +478,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetShaderInfoLog(
const volatile gles2::cmds::GetShaderInfoLog& c =
*static_cast<const volatile gles2::cmds::GetShaderInfoLog*>(cmd_data);
GLuint shader = static_cast<GLuint>(c.shader);
- uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
std::string infolog;
error::Error error = DoGetShaderInfoLog(shader, &infolog);
@@ -503,9 +499,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetShaderPrecisionFormat(
cmd_data);
GLenum shader_type = static_cast<GLenum>(c.shadertype);
GLenum precision_type = static_cast<GLenum>(c.precisiontype);
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetShaderPrecisionFormat::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -536,7 +535,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetShaderSource(
const volatile gles2::cmds::GetShaderSource& c =
*static_cast<const volatile gles2::cmds::GetShaderSource*>(cmd_data);
GLuint shader = static_cast<GLuint>(c.shader);
- uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
std::string source;
error::Error error = DoGetShaderSource(shader, &source);
@@ -556,6 +555,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetString(
const volatile gles2::cmds::GetString& c =
*static_cast<const volatile gles2::cmds::GetString*>(cmd_data);
GLenum name = static_cast<GLenum>(c.name);
+ uint32_t bucket_id = c.bucket_id;
const char* str = nullptr;
error::Error error = DoGetString(name, &str);
@@ -565,7 +565,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetString(
if (!str) {
return error::kOutOfBounds;
}
- Bucket* bucket = CreateBucket(c.bucket_id);
+ Bucket* bucket = CreateBucket(bucket_id);
bucket->SetFromString(str);
return error::kNoError;
@@ -580,9 +580,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetTransformFeedbackVarying(
GLuint program = static_cast<GLuint>(c.program);
GLuint index = static_cast<GLuint>(c.index);
uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
typedef cmds::GetTransformFeedbackVarying::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -614,7 +617,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformBlockIndex(
const volatile gles2::cmds::GetUniformBlockIndex& c =
*static_cast<const volatile gles2::cmds::GetUniformBlockIndex*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t index_shm_id = c.index_shm_id;
+ uint32_t index_shm_offset = c.index_shm_offset;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -622,19 +629,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformBlockIndex(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- GLint* index = GetSharedMemoryAs<GLint*>(c.index_shm_id, c.index_shm_offset,
- sizeof(GLint));
+ GLint* index =
+ GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint));
if (!index) {
return error::kOutOfBounds;
}
if (*index != -1) {
return error::kInvalidArguments;
}
- error::Error error = DoGetUniformBlockIndex(program, name_str.c_str(), index);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoGetUniformBlockIndex(program, name_str.c_str(), index);
}
error::Error GLES2DecoderPassthroughImpl::HandleGetUniformfv(
@@ -644,12 +647,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformfv(
*static_cast<const volatile gles2::cmds::GetUniformfv*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLint location = static_cast<GLint>(c.location);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetUniformfv::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size);
- GLfloat* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, sizeof(Result), &buffer_size);
+ GLfloat* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -673,12 +679,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformiv(
*static_cast<const volatile gles2::cmds::GetUniformiv*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLint location = static_cast<GLint>(c.location);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetUniformiv::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size);
- GLint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, sizeof(Result), &buffer_size);
+ GLint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -702,12 +711,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformuiv(
*static_cast<const volatile gles2::cmds::GetUniformuiv*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLint location = static_cast<GLint>(c.location);
+ uint32_t params_shm_id = c.params_shm_id;
+ uint32_t params_shm_offset = c.params_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetUniformuiv::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size);
- GLuint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ params_shm_id, params_shm_offset, sizeof(Result), &buffer_size);
+ GLuint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -730,7 +742,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformIndices(
const volatile gles2::cmds::GetUniformIndices& c =
*static_cast<const volatile gles2::cmds::GetUniformIndices*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.names_bucket_id);
+ uint32_t names_bucket_id = c.names_bucket_id;
+ uint32_t indices_shm_id = c.indices_shm_id;
+ uint32_t indices_shm_offset = c.indices_shm_offset;
+
+ Bucket* bucket = GetBucket(names_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -742,10 +758,10 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformIndices(
}
typedef cmds::GetUniformIndices::Result Result;
Result* result = GetSharedMemoryAs<Result*>(
- c.indices_shm_id, c.indices_shm_offset,
+ indices_shm_id, indices_shm_offset,
Result::ComputeSize(static_cast<size_t>(count)));
- GLuint* indices = result ? result->GetData() : NULL;
- if (indices == NULL) {
+ GLuint* indices = result ? result->GetData() : nullptr;
+ if (indices == nullptr) {
return error::kOutOfBounds;
}
// Check that the client initialized the result.
@@ -767,7 +783,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformLocation(
const volatile gles2::cmds::GetUniformLocation& c =
*static_cast<const volatile gles2::cmds::GetUniformLocation*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t location_shm_id = c.location_shm_id;
+ uint32_t location_shm_offset = c.location_shm_offset;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -776,19 +796,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformLocation(
return error::kInvalidArguments;
}
GLint* location = GetSharedMemoryAs<GLint*>(
- c.location_shm_id, c.location_shm_offset, sizeof(GLint));
+ location_shm_id, location_shm_offset, sizeof(GLint));
if (!location) {
return error::kOutOfBounds;
}
if (*location != -1) {
return error::kInvalidArguments;
}
- error::Error error =
- DoGetUniformLocation(program, name_str.c_str(), location);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoGetUniformLocation(program, name_str.c_str(), location);
}
error::Error GLES2DecoderPassthroughImpl::HandleGetVertexAttribPointerv(
@@ -799,12 +814,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetVertexAttribPointerv(
cmd_data);
GLuint index = static_cast<GLuint>(c.index);
GLenum pname = static_cast<GLenum>(c.pname);
+ uint32_t pointer_shm_id = c.pointer_shm_id;
+ uint32_t pointer_shm_offset = c.pointer_shm_offset;
+
unsigned int buffer_size = 0;
typedef cmds::GetVertexAttribPointerv::Result Result;
Result* result = GetSharedMemoryAndSizeAs<Result*>(
- c.pointer_shm_id, c.pointer_shm_offset, sizeof(Result), &buffer_size);
- GLuint* params = result ? result->GetData() : NULL;
- if (params == NULL) {
+ pointer_shm_id, pointer_shm_offset, sizeof(Result), &buffer_size);
+ GLuint* params = result ? result->GetData() : nullptr;
+ if (params == nullptr) {
return error::kOutOfBounds;
}
GLsizei bufsize = Result::ComputeMaxResults(buffer_size);
@@ -828,11 +846,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePixelStorei(
*static_cast<const volatile gles2::cmds::PixelStorei*>(cmd_data);
GLenum pname = static_cast<GLuint>(c.pname);
GLint param = static_cast<GLint>(c.param);
- error::Error error = DoPixelStorei(pname, param);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoPixelStorei(pname, param);
}
error::Error GLES2DecoderPassthroughImpl::HandleReadPixels(
@@ -848,16 +863,27 @@ error::Error GLES2DecoderPassthroughImpl::HandleReadPixels(
GLenum type = static_cast<GLenum>(c.type);
uint32_t pixels_shm_id = c.pixels_shm_id;
uint32_t pixels_shm_offset = c.pixels_shm_offset;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+ GLboolean async = static_cast<GLboolean>(c.async);
+
+ bool pack_buffer_bound = bound_buffers_[GL_PIXEL_PACK_BUFFER] != 0;
uint8_t* pixels = nullptr;
unsigned int buffer_size = 0;
- if (c.pixels_shm_id != 0) {
+ if (pixels_shm_id != 0) {
+ if (pack_buffer_bound) {
+ return error::kInvalidArguments;
+ }
pixels = GetSharedMemoryAndSizeAs<uint8_t*>(
pixels_shm_id, pixels_shm_offset, 0, &buffer_size);
if (!pixels) {
return error::kOutOfBounds;
}
} else {
+ if (!pack_buffer_bound) {
+ return error::kInvalidArguments;
+ }
pixels =
reinterpret_cast<uint8_t*>(static_cast<intptr_t>(pixels_shm_offset));
}
@@ -867,8 +893,16 @@ error::Error GLES2DecoderPassthroughImpl::HandleReadPixels(
GLsizei columns = 0;
GLsizei rows = 0;
int32_t success = 0;
- error::Error error = DoReadPixels(x, y, width, height, format, type, bufsize,
- &length, &columns, &rows, pixels, &success);
+ error::Error error = error::kNoError;
+ if (async && feature_info_->feature_flags().use_async_readpixels &&
+ !pack_buffer_bound) {
+ error = DoReadPixelsAsync(
+ x, y, width, height, format, type, bufsize, &length, &columns, &rows,
+ pixels_shm_id, pixels_shm_offset, result_shm_id, result_shm_offset);
+ } else {
+ error = DoReadPixels(x, y, width, height, format, type, bufsize, &length,
+ &columns, &rows, pixels, &success);
+ }
if (error != error::kNoError) {
return error;
}
@@ -876,20 +910,17 @@ error::Error GLES2DecoderPassthroughImpl::HandleReadPixels(
return error::kOutOfBounds;
}
- typedef cmds::ReadPixels::Result Result;
- Result* result = nullptr;
- if (c.result_shm_id != 0) {
- result = GetSharedMemoryAs<Result*>(c.result_shm_id, c.result_shm_offset,
- sizeof(*result));
+ if (result_shm_id != 0) {
+ typedef cmds::ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>(
+ result_shm_id, result_shm_offset, sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
if (result->success != 0) {
return error::kInvalidArguments;
}
- }
- if (result) {
result->success = success;
result->row_length = static_cast<uint32_t>(columns);
result->num_rows = static_cast<uint32_t>(rows);
@@ -905,25 +936,25 @@ error::Error GLES2DecoderPassthroughImpl::HandleShaderBinary(
*static_cast<const volatile gles2::cmds::ShaderBinary*>(cmd_data);
GLsizei n = static_cast<GLsizei>(c.n);
GLsizei length = static_cast<GLsizei>(c.length);
+ GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
+ uint32_t shaders_shm_id = c.shaders_shm_id;
+ uint32_t shaders_shm_offset = c.shaders_shm_offset;
+ uint32_t binary_shm_id = c.binary_shm_id;
+ uint32_t binary_shm_offset = c.binary_shm_offset;
+
uint32_t data_size;
if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
return error::kOutOfBounds;
}
const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
- c.shaders_shm_id, c.shaders_shm_offset, data_size);
- GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
- const void* binary = GetSharedMemoryAs<const void*>(
- c.binary_shm_id, c.binary_shm_offset, length);
- if (shaders == NULL || binary == NULL) {
+ shaders_shm_id, shaders_shm_offset, data_size);
+ const void* binary =
+ GetSharedMemoryAs<const void*>(binary_shm_id, binary_shm_offset, length);
+ if (shaders == nullptr || binary == nullptr) {
return error::kOutOfBounds;
}
- error::Error error = DoShaderBinary(n, shaders, binaryformat, binary, length);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoShaderBinary(n, shaders, binaryformat, binary, length);
}
error::Error GLES2DecoderPassthroughImpl::HandleTexImage2D(
@@ -1074,12 +1105,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleUniformBlockBinding(
GLuint index = static_cast<GLuint>(c.index);
GLuint binding = static_cast<GLuint>(c.binding);
- error::Error error = DoUniformBlockBinding(program, index, binding);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoUniformBlockBinding(program, index, binding);
}
error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribIPointer(
@@ -1094,12 +1120,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribIPointer(
GLsizei offset = static_cast<GLsizei>(c.offset);
const void* ptr = reinterpret_cast<const void*>(offset);
- error::Error error = DoVertexAttribIPointer(index, size, type, stride, ptr);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoVertexAttribIPointer(index, size, type, stride, ptr);
}
error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribPointer(
@@ -1115,13 +1136,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribPointer(
GLsizei offset = static_cast<GLsizei>(c.offset);
const void* ptr = reinterpret_cast<const void*>(offset);
- error::Error error =
- DoVertexAttribPointer(index, size, type, normalized, stride, ptr);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoVertexAttribPointer(index, size, type, normalized, stride, ptr);
}
error::Error GLES2DecoderPassthroughImpl::HandleWaitSync(
@@ -1133,12 +1148,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleWaitSync(
const GLbitfield flags = static_cast<GLbitfield>(c.flags);
const GLuint64 timeout = c.timeout();
- error::Error error = DoWaitSync(sync, flags, timeout);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoWaitSync(sync, flags, timeout);
}
error::Error GLES2DecoderPassthroughImpl::HandleQueryCounterEXT(
@@ -1148,17 +1158,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleQueryCounterEXT(
*static_cast<const volatile gles2::cmds::QueryCounterEXT*>(cmd_data);
GLuint id = static_cast<GLuint>(c.id);
GLenum target = static_cast<GLenum>(c.target);
- int32_t sync_shm_id = static_cast<int32_t>(c.sync_data_shm_id);
- uint32_t sync_shm_offset = static_cast<uint32_t>(c.sync_data_shm_offset);
+ uint32_t sync_shm_id = c.sync_data_shm_id;
+ uint32_t sync_shm_offset = c.sync_data_shm_offset;
uint32_t submit_count = static_cast<GLuint>(c.submit_count);
- error::Error error =
- DoQueryCounterEXT(id, target, sync_shm_id, sync_shm_offset, submit_count);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoQueryCounterEXT(id, target, sync_shm_id, sync_shm_offset,
+ submit_count);
}
error::Error GLES2DecoderPassthroughImpl::HandleBeginQueryEXT(
@@ -1168,16 +1173,10 @@ error::Error GLES2DecoderPassthroughImpl::HandleBeginQueryEXT(
*static_cast<const volatile gles2::cmds::BeginQueryEXT*>(cmd_data);
GLenum target = static_cast<GLenum>(c.target);
GLuint id = static_cast<GLuint>(c.id);
- int32_t sync_shm_id = static_cast<int32_t>(c.sync_data_shm_id);
- uint32_t sync_shm_offset = static_cast<uint32_t>(c.sync_data_shm_offset);
-
- error::Error error =
- DoBeginQueryEXT(target, id, sync_shm_id, sync_shm_offset);
- if (error != error::kNoError) {
- return error;
- }
+ uint32_t sync_shm_id = c.sync_data_shm_id;
+ uint32_t sync_shm_offset = c.sync_data_shm_offset;
- return error::kNoError;
+ return DoBeginQueryEXT(target, id, sync_shm_id, sync_shm_offset);
}
error::Error GLES2DecoderPassthroughImpl::HandleEndQueryEXT(
@@ -1188,12 +1187,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleEndQueryEXT(
GLenum target = static_cast<GLenum>(c.target);
uint32_t submit_count = static_cast<GLuint>(c.submit_count);
- error::Error error = DoEndQueryEXT(target, submit_count);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoEndQueryEXT(target, submit_count);
}
error::Error GLES2DecoderPassthroughImpl::HandleSetDisjointValueSyncCHROMIUM(
@@ -1202,16 +1196,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleSetDisjointValueSyncCHROMIUM(
const volatile gles2::cmds::SetDisjointValueSyncCHROMIUM& c =
*static_cast<const volatile gles2::cmds::SetDisjointValueSyncCHROMIUM*>(
cmd_data);
+ uint32_t sync_data_shm_id = c.sync_data_shm_id;
+ uint32_t sync_data_shm_offset = c.sync_data_shm_offset;
+
DisjointValueSync* sync = GetSharedMemoryAs<DisjointValueSync*>(
- c.sync_data_shm_id, c.sync_data_shm_offset, sizeof(*sync));
+ sync_data_shm_id, sync_data_shm_offset, sizeof(*sync));
if (!sync) {
return error::kOutOfBounds;
}
- error::Error error = DoSetDisjointValueSyncCHROMIUM(sync);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoSetDisjointValueSyncCHROMIUM(sync);
}
error::Error GLES2DecoderPassthroughImpl::HandleInsertEventMarkerEXT(
@@ -1219,7 +1212,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleInsertEventMarkerEXT(
const volatile void* cmd_data) {
const volatile gles2::cmds::InsertEventMarkerEXT& c =
*static_cast<const volatile gles2::cmds::InsertEventMarkerEXT*>(cmd_data);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = GetBucket(bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
@@ -1228,11 +1222,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleInsertEventMarkerEXT(
if (!bucket->GetAsString(&str)) {
return error::kInvalidArguments;
}
- error::Error error = DoInsertEventMarkerEXT(0, str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoInsertEventMarkerEXT(0, str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandlePushGroupMarkerEXT(
@@ -1240,7 +1230,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePushGroupMarkerEXT(
const volatile void* cmd_data) {
const volatile gles2::cmds::PushGroupMarkerEXT& c =
*static_cast<const volatile gles2::cmds::PushGroupMarkerEXT*>(cmd_data);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = GetBucket(bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
@@ -1249,11 +1240,7 @@ error::Error GLES2DecoderPassthroughImpl::HandlePushGroupMarkerEXT(
if (!bucket->GetAsString(&str)) {
return error::kInvalidArguments;
}
- error::Error error = DoPushGroupMarkerEXT(0, str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoPushGroupMarkerEXT(0, str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleEnableFeatureCHROMIUM(
@@ -1262,13 +1249,17 @@ error::Error GLES2DecoderPassthroughImpl::HandleEnableFeatureCHROMIUM(
const volatile gles2::cmds::EnableFeatureCHROMIUM& c =
*static_cast<const volatile gles2::cmds::EnableFeatureCHROMIUM*>(
cmd_data);
- Bucket* bucket = GetBucket(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+
+ Bucket* bucket = GetBucket(bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
typedef cmds::EnableFeatureCHROMIUM::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -1298,10 +1289,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleMapBufferRange(
GLbitfield access = static_cast<GLbitfield>(c.access);
GLintptr offset = static_cast<GLintptr>(c.offset);
GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
+ uint32_t result_shm_id = c.result_shm_id;
+ uint32_t result_shm_offset = c.result_shm_offset;
+ uint32_t data_shm_id = c.data_shm_id;
+ uint32_t data_shm_offset = c.data_shm_offset;
typedef cmds::MapBufferRange::Result Result;
- Result* result = GetSharedMemoryAs<Result*>(
- c.result_shm_id, c.result_shm_offset, sizeof(*result));
+ Result* result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
+ sizeof(*result));
if (!result) {
return error::kOutOfBounds;
}
@@ -1310,20 +1305,15 @@ error::Error GLES2DecoderPassthroughImpl::HandleMapBufferRange(
return error::kInvalidArguments;
}
uint8_t* mem =
- GetSharedMemoryAs<uint8_t*>(c.data_shm_id, c.data_shm_offset, size);
+ GetSharedMemoryAs<uint8_t*>(data_shm_id, data_shm_offset, size);
if (!mem) {
return error::kOutOfBounds;
}
- error::Error error =
- DoMapBufferRange(target, offset, size, access, mem, c.data_shm_id,
- c.data_shm_offset, result);
- if (error != error::kNoError) {
- DCHECK(*result == 0);
- return error;
- }
-
- return error::kNoError;
+ error::Error error = DoMapBufferRange(target, offset, size, access, mem,
+ data_shm_id, data_shm_offset, result);
+ DCHECK(error == error::kNoError || *result == 0);
+ return error;
}
error::Error GLES2DecoderPassthroughImpl::HandleUnmapBuffer(
@@ -1332,11 +1322,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleUnmapBuffer(
const volatile gles2::cmds::UnmapBuffer& c =
*static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data);
GLenum target = static_cast<GLenum>(c.target);
- error::Error error = DoUnmapBuffer(target);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoUnmapBuffer(target);
}
error::Error GLES2DecoderPassthroughImpl::HandleResizeCHROMIUM(
@@ -1349,12 +1336,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleResizeCHROMIUM(
GLfloat scale_factor = static_cast<GLfloat>(c.scale_factor);
GLenum color_space = static_cast<GLenum>(c.color_space);
GLboolean has_alpha = static_cast<GLboolean>(c.alpha);
- error::Error error =
- DoResizeCHROMIUM(width, height, scale_factor, color_space, has_alpha);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoResizeCHROMIUM(width, height, scale_factor, color_space, has_alpha);
}
error::Error
@@ -1365,6 +1348,8 @@ GLES2DecoderPassthroughImpl::HandleGetRequestableExtensionsCHROMIUM(
*static_cast<
const volatile gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
cmd_data);
+ uint32_t bucket_id = c.bucket_id;
+
const char* str = nullptr;
error::Error error = DoGetRequestableExtensionsCHROMIUM(&str);
if (error != error::kNoError) {
@@ -1373,7 +1358,7 @@ GLES2DecoderPassthroughImpl::HandleGetRequestableExtensionsCHROMIUM(
if (!str) {
return error::kOutOfBounds;
}
- Bucket* bucket = CreateBucket(c.bucket_id);
+ Bucket* bucket = CreateBucket(bucket_id);
bucket->SetFromString(str);
return error::kNoError;
@@ -1385,7 +1370,9 @@ error::Error GLES2DecoderPassthroughImpl::HandleRequestExtensionCHROMIUM(
const volatile gles2::cmds::RequestExtensionCHROMIUM& c =
*static_cast<const volatile gles2::cmds::RequestExtensionCHROMIUM*>(
cmd_data);
- Bucket* bucket = GetBucket(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+
+ Bucket* bucket = GetBucket(bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -1393,11 +1380,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleRequestExtensionCHROMIUM(
if (!bucket->GetAsString(&feature_str)) {
return error::kInvalidArguments;
}
- error::Error error = DoRequestExtensionCHROMIUM(feature_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoRequestExtensionCHROMIUM(feature_str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleGetProgramInfoCHROMIUM(
@@ -1407,8 +1390,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetProgramInfoCHROMIUM(
*static_cast<const volatile gles2::cmds::GetProgramInfoCHROMIUM*>(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
-
uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = CreateBucket(bucket_id);
bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
@@ -1431,8 +1414,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformBlocksCHROMIUM(
*static_cast<const volatile gles2::cmds::GetUniformBlocksCHROMIUM*>(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
-
uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = CreateBucket(bucket_id);
bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
@@ -1457,8 +1440,8 @@ GLES2DecoderPassthroughImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
const volatile gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
-
uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = CreateBucket(bucket_id);
bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
@@ -1481,8 +1464,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetUniformsES3CHROMIUM(
*static_cast<const volatile gles2::cmds::GetUniformsES3CHROMIUM*>(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
-
uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = CreateBucket(bucket_id);
bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
@@ -1505,6 +1488,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetTranslatedShaderSourceANGLE(
*static_cast<const volatile gles2::cmds::GetTranslatedShaderSourceANGLE*>(
cmd_data);
GLuint shader = static_cast<GLuint>(c.shader);
+ uint32_t bucket_id = c.bucket_id;
std::string source;
error::Error error = DoGetTranslatedShaderSourceANGLE(shader, &source);
@@ -1512,7 +1496,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetTranslatedShaderSourceANGLE(
return error;
}
- Bucket* bucket = CreateBucket(c.bucket_id);
+ Bucket* bucket = CreateBucket(bucket_id);
bucket->SetFromString(source.c_str());
return error::kNoError;
@@ -1528,11 +1512,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePostSubBufferCHROMIUM(
GLint y = static_cast<GLint>(c.y);
GLint width = static_cast<GLint>(c.width);
GLint height = static_cast<GLint>(c.height);
- error::Error error = DoPostSubBufferCHROMIUM(x, y, width, height);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoPostSubBufferCHROMIUM(x, y, width, height);
}
error::Error GLES2DecoderPassthroughImpl::HandleDrawArraysInstancedANGLE(
@@ -1545,12 +1526,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleDrawArraysInstancedANGLE(
GLint first = static_cast<GLint>(c.first);
GLsizei count = static_cast<GLsizei>(c.count);
GLsizei primcount = static_cast<GLsizei>(c.primcount);
- error::Error error =
- DoDrawArraysInstancedANGLE(mode, first, count, primcount);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoDrawArraysInstancedANGLE(mode, first, count, primcount);
}
error::Error GLES2DecoderPassthroughImpl::HandleDrawElementsInstancedANGLE(
@@ -1565,12 +1542,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleDrawElementsInstancedANGLE(
const GLvoid* indices =
reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(c.index_offset));
GLsizei primcount = static_cast<GLsizei>(c.primcount);
- error::Error error =
- DoDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
}
error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribDivisorANGLE(
@@ -1581,11 +1554,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleVertexAttribDivisorANGLE(
cmd_data);
GLuint index = static_cast<GLuint>(c.index);
GLuint divisor = static_cast<GLuint>(c.divisor);
- error::Error error = DoVertexAttribDivisorANGLE(index, divisor);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoVertexAttribDivisorANGLE(index, divisor);
}
error::Error
@@ -1598,7 +1568,9 @@ GLES2DecoderPassthroughImpl::HandleBindUniformLocationCHROMIUMBucket(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLint location = static_cast<GLint>(c.location);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -1606,12 +1578,7 @@ GLES2DecoderPassthroughImpl::HandleBindUniformLocationCHROMIUMBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- error::Error error =
- DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleTraceBeginCHROMIUM(
@@ -1619,8 +1586,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleTraceBeginCHROMIUM(
const volatile void* cmd_data) {
const volatile gles2::cmds::TraceBeginCHROMIUM& c =
*static_cast<const volatile gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
- Bucket* category_bucket = GetBucket(c.category_bucket_id);
- Bucket* name_bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+ uint32_t category_bucket_id = c.category_bucket_id;
+
+ Bucket* category_bucket = GetBucket(category_bucket_id);
+ Bucket* name_bucket = GetBucket(name_bucket_id);
if (!category_bucket || category_bucket->size() == 0 || !name_bucket ||
name_bucket->size() == 0) {
return error::kInvalidArguments;
@@ -1633,22 +1603,13 @@ error::Error GLES2DecoderPassthroughImpl::HandleTraceBeginCHROMIUM(
return error::kInvalidArguments;
}
- error::Error error =
- DoTraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoTraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleDescheduleUntilFinishedCHROMIUM(
uint32_t immediate_data_size,
const volatile void* cmd_data) {
- error::Error error = DoDescheduleUntilFinishedCHROMIUM();
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoDescheduleUntilFinishedCHROMIUM();
}
error::Error GLES2DecoderPassthroughImpl::HandleInsertFenceSyncCHROMIUM(
@@ -1658,11 +1619,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleInsertFenceSyncCHROMIUM(
*static_cast<const volatile gles2::cmds::InsertFenceSyncCHROMIUM*>(
cmd_data);
GLuint64 release_count = c.release_count();
- error::Error error = DoInsertFenceSyncCHROMIUM(release_count);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoInsertFenceSyncCHROMIUM(release_count);
}
error::Error GLES2DecoderPassthroughImpl::HandleWaitSyncTokenCHROMIUM(
@@ -1673,9 +1631,9 @@ error::Error GLES2DecoderPassthroughImpl::HandleWaitSyncTokenCHROMIUM(
cmd_data);
CommandBufferNamespace namespace_id =
static_cast<gpu::CommandBufferNamespace>(c.namespace_id);
+ const uint64_t release_count = c.release_count();
CommandBufferId command_buffer_id =
CommandBufferId::FromUnsafeValue(c.command_buffer_id());
- const uint64_t release_count = c.release_count();
const CommandBufferNamespace kMinNamespaceId =
CommandBufferNamespace::INVALID;
@@ -1686,22 +1644,14 @@ error::Error GLES2DecoderPassthroughImpl::HandleWaitSyncTokenCHROMIUM(
namespace_id = gpu::CommandBufferNamespace::INVALID;
}
- error::Error error =
- DoWaitSyncTokenCHROMIUM(namespace_id, command_buffer_id, release_count);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoWaitSyncTokenCHROMIUM(namespace_id, command_buffer_id,
+ release_count);
}
error::Error GLES2DecoderPassthroughImpl::HandleDiscardBackbufferCHROMIUM(
uint32_t immediate_data_size,
const volatile void* cmd_data) {
- error::Error error = DoDiscardBackbufferCHROMIUM();
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoDiscardBackbufferCHROMIUM();
}
error::Error GLES2DecoderPassthroughImpl::HandleScheduleOverlayPlaneCHROMIUM(
@@ -1721,13 +1671,10 @@ error::Error GLES2DecoderPassthroughImpl::HandleScheduleOverlayPlaneCHROMIUM(
GLfloat uv_y = static_cast<GLfloat>(c.uv_x);
GLfloat uv_width = static_cast<GLfloat>(c.uv_x);
GLfloat uv_height = static_cast<GLfloat>(c.uv_x);
- error::Error error = DoScheduleOverlayPlaneCHROMIUM(
+
+ return DoScheduleOverlayPlaneCHROMIUM(
plane_z_order, plane_transform, overlay_texture_id, bounds_x, bounds_y,
bounds_width, bounds_height, uv_x, uv_y, uv_width, uv_height);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
}
error::Error
@@ -1738,22 +1685,21 @@ GLES2DecoderPassthroughImpl::HandleScheduleCALayerSharedStateCHROMIUM(
*static_cast<
const volatile gles2::cmds::ScheduleCALayerSharedStateCHROMIUM*>(
cmd_data);
- const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset,
+ GLfloat opacity = static_cast<GLfloat>(c.opacity);
+ GLboolean is_clipped = static_cast<GLboolean>(c.is_clipped);
+ GLint sorting_context_id = static_cast<GLint>(c.sorting_context_id);
+ uint32_t shm_id = c.shm_id;
+ uint32_t shm_offset = c.shm_offset;
+
+ const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(shm_id, shm_offset,
20 * sizeof(GLfloat));
if (!mem) {
return error::kOutOfBounds;
}
- GLfloat opacity = static_cast<GLfloat>(c.opacity);
- GLboolean is_clipped = static_cast<GLboolean>(c.is_clipped);
const GLfloat* clip_rect = mem + 0;
- GLint sorting_context_id = static_cast<GLint>(c.sorting_context_id);
const GLfloat* transform = mem + 4;
- error::Error error = DoScheduleCALayerSharedStateCHROMIUM(
- opacity, is_clipped, clip_rect, sorting_context_id, transform);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoScheduleCALayerSharedStateCHROMIUM(opacity, is_clipped, clip_rect,
+ sorting_context_id, transform);
}
error::Error GLES2DecoderPassthroughImpl::HandleScheduleCALayerCHROMIUM(
@@ -1762,23 +1708,21 @@ error::Error GLES2DecoderPassthroughImpl::HandleScheduleCALayerCHROMIUM(
const volatile gles2::cmds::ScheduleCALayerCHROMIUM& c =
*static_cast<const volatile gles2::cmds::ScheduleCALayerCHROMIUM*>(
cmd_data);
- const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset,
+ GLuint contents_texture_id = static_cast<GLint>(c.contents_texture_id);
+ GLuint background_color = static_cast<GLuint>(c.background_color);
+ GLuint edge_aa_mask = static_cast<GLuint>(c.edge_aa_mask);
+ uint32_t shm_id = c.shm_id;
+ uint32_t shm_offset = c.shm_offset;
+
+ const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(shm_id, shm_offset,
8 * sizeof(GLfloat));
if (!mem) {
return error::kOutOfBounds;
}
- GLuint contents_texture_id = static_cast<GLint>(c.contents_texture_id);
const GLfloat* contents_rect = mem;
- GLuint background_color = static_cast<GLuint>(c.background_color);
- GLuint edge_aa_mask = static_cast<GLuint>(c.edge_aa_mask);
const GLfloat* bounds_rect = mem + 4;
- error::Error error =
- DoScheduleCALayerCHROMIUM(contents_texture_id, contents_rect,
- background_color, edge_aa_mask, bounds_rect);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoScheduleCALayerCHROMIUM(contents_texture_id, contents_rect,
+ background_color, edge_aa_mask, bounds_rect);
}
error::Error
@@ -1789,22 +1733,21 @@ GLES2DecoderPassthroughImpl::HandleScheduleDCLayerSharedStateCHROMIUM(
*static_cast<
const volatile gles2::cmds::ScheduleDCLayerSharedStateCHROMIUM*>(
cmd_data);
- const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset,
+ GLfloat opacity = static_cast<GLfloat>(c.opacity);
+ GLboolean is_clipped = static_cast<GLboolean>(c.is_clipped);
+ GLint z_order = static_cast<GLint>(c.z_order);
+ uint32_t shm_id = c.shm_id;
+ uint32_t shm_offset = c.shm_offset;
+
+ const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(shm_id, shm_offset,
20 * sizeof(GLfloat));
if (!mem) {
return error::kOutOfBounds;
}
- GLfloat opacity = static_cast<GLfloat>(c.opacity);
- GLboolean is_clipped = static_cast<GLboolean>(c.is_clipped);
const GLfloat* clip_rect = mem + 0;
- GLint z_order = static_cast<GLint>(c.z_order);
const GLfloat* transform = mem + 4;
- error::Error error = DoScheduleDCLayerSharedStateCHROMIUM(
- opacity, is_clipped, clip_rect, z_order, transform);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoScheduleDCLayerSharedStateCHROMIUM(opacity, is_clipped, clip_rect,
+ z_order, transform);
}
error::Error GLES2DecoderPassthroughImpl::HandleScheduleDCLayerCHROMIUM(
@@ -1813,13 +1756,19 @@ error::Error GLES2DecoderPassthroughImpl::HandleScheduleDCLayerCHROMIUM(
const volatile gles2::cmds::ScheduleDCLayerCHROMIUM& c =
*static_cast<const volatile gles2::cmds::ScheduleDCLayerCHROMIUM*>(
cmd_data);
+ GLuint background_color = static_cast<GLuint>(c.background_color);
+ GLuint edge_aa_mask = static_cast<GLuint>(c.edge_aa_mask);
+ GLenum filter = static_cast<GLenum>(c.filter);
+ const GLsizei num_textures = c.num_textures;
+ uint32_t shm_id = c.shm_id;
+ uint32_t shm_offset = c.shm_offset;
+
unsigned int size;
const GLfloat* mem = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.shm_id, c.shm_offset, 8 * sizeof(GLfloat), &size);
+ shm_id, shm_offset, 8 * sizeof(GLfloat), &size);
if (!mem) {
return error::kOutOfBounds;
}
- const GLsizei num_textures = c.num_textures;
if (num_textures < 0 || (size - 8 * sizeof(GLfloat)) / sizeof(GLuint) <
static_cast<GLuint>(num_textures)) {
return error::kOutOfBounds;
@@ -1827,17 +1776,10 @@ error::Error GLES2DecoderPassthroughImpl::HandleScheduleDCLayerCHROMIUM(
const volatile GLuint* contents_texture_ids =
reinterpret_cast<const volatile GLuint*>(mem + 8);
const GLfloat* contents_rect = mem;
- GLuint background_color = static_cast<GLuint>(c.background_color);
- GLuint edge_aa_mask = static_cast<GLuint>(c.edge_aa_mask);
- GLenum filter = static_cast<GLenum>(c.filter);
const GLfloat* bounds_rect = mem + 4;
- error::Error error = DoScheduleDCLayerCHROMIUM(
- num_textures, contents_texture_ids, contents_rect, background_color,
- edge_aa_mask, filter, bounds_rect);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoScheduleDCLayerCHROMIUM(num_textures, contents_texture_ids,
+ contents_rect, background_color,
+ edge_aa_mask, filter, bounds_rect);
}
error::Error GLES2DecoderPassthroughImpl::HandleSetColorSpaceForScanoutCHROMIUM(
@@ -1854,11 +1796,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleGenPathsCHROMIUM(
*static_cast<const volatile gles2::cmds::GenPathsCHROMIUM*>(cmd_data);
GLuint path = static_cast<GLuint>(c.first_client_id);
GLsizei range = static_cast<GLsizei>(c.range);
- error::Error error = DoGenPathsCHROMIUM(path, range);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoGenPathsCHROMIUM(path, range);
}
error::Error GLES2DecoderPassthroughImpl::HandleDeletePathsCHROMIUM(
@@ -1868,11 +1807,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleDeletePathsCHROMIUM(
*static_cast<const volatile gles2::cmds::DeletePathsCHROMIUM*>(cmd_data);
GLuint path = static_cast<GLuint>(c.first_client_id);
GLsizei range = static_cast<GLsizei>(c.range);
- error::Error error = DoDeletePathsCHROMIUM(path, range);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoDeletePathsCHROMIUM(path, range);
}
error::Error GLES2DecoderPassthroughImpl::HandlePathCommandsCHROMIUM(
@@ -1882,10 +1818,15 @@ error::Error GLES2DecoderPassthroughImpl::HandlePathCommandsCHROMIUM(
*static_cast<const volatile gles2::cmds::PathCommandsCHROMIUM*>(cmd_data);
GLuint path = static_cast<GLuint>(c.path);
GLsizei num_commands = static_cast<GLsizei>(c.numCommands);
+ GLsizei num_coords = static_cast<GLsizei>(c.numCoords);
+ GLenum coord_type = static_cast<GLenum>(c.coordType);
+ uint32_t commands_shm_id = c.commands_shm_id;
+ uint32_t commands_shm_offset = c.commands_shm_offset;
+ uint32_t coords_shm_id = c.coords_shm_id;
+ uint32_t coords_shm_offset = c.coords_shm_offset;
+
const GLubyte* commands = nullptr;
if (num_commands > 0) {
- uint32_t commands_shm_id = static_cast<uint32_t>(c.commands_shm_id);
- uint32_t commands_shm_offset = static_cast<uint32_t>(c.commands_shm_offset);
if (commands_shm_id != 0 || commands_shm_offset != 0) {
commands = GetSharedMemoryAs<const GLubyte*>(
commands_shm_id, commands_shm_offset, num_commands);
@@ -1894,13 +1835,9 @@ error::Error GLES2DecoderPassthroughImpl::HandlePathCommandsCHROMIUM(
return error::kOutOfBounds;
}
}
- GLsizei num_coords = static_cast<GLsizei>(c.numCoords);
- GLenum coord_type = static_cast<GLenum>(c.coordType);
const GLvoid* coords = nullptr;
GLsizei coords_bufsize = 0;
if (num_coords > 0) {
- uint32_t coords_shm_id = static_cast<uint32_t>(c.coords_shm_id);
- uint32_t coords_shm_offset = static_cast<uint32_t>(c.coords_shm_offset);
if (coords_shm_id != 0 || coords_shm_offset != 0) {
unsigned int memory_size = 0;
coords = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -1913,14 +1850,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePathCommandsCHROMIUM(
}
}
- error::Error error =
- DoPathCommandsCHROMIUM(path, num_commands, commands, num_coords,
- coord_type, coords, coords_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
+ return DoPathCommandsCHROMIUM(path, num_commands, commands, num_coords,
+ coord_type, coords, coords_bufsize);
}
error::Error GLES2DecoderPassthroughImpl::HandlePathParameterfCHROMIUM(
@@ -1932,11 +1863,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePathParameterfCHROMIUM(
GLuint path = static_cast<GLuint>(c.path);
GLenum pname = static_cast<GLenum>(c.pname);
GLfloat value = static_cast<GLfloat>(c.value);
- error::Error error = DoPathParameterfCHROMIUM(path, pname, value);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoPathParameterfCHROMIUM(path, pname, value);
}
error::Error GLES2DecoderPassthroughImpl::HandlePathParameteriCHROMIUM(
@@ -1948,11 +1876,8 @@ error::Error GLES2DecoderPassthroughImpl::HandlePathParameteriCHROMIUM(
GLuint path = static_cast<GLuint>(c.path);
GLenum pname = static_cast<GLenum>(c.pname);
GLint value = static_cast<GLint>(c.value);
- error::Error error = DoPathParameteriCHROMIUM(path, pname, value);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoPathParameteriCHROMIUM(path, pname, value);
}
error::Error GLES2DecoderPassthroughImpl::HandleStencilFillPathCHROMIUM(
@@ -1964,11 +1889,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleStencilFillPathCHROMIUM(
GLuint path = static_cast<GLuint>(c.path);
GLenum fill_mode = static_cast<GLenum>(c.fillMode);
GLuint mask = static_cast<GLuint>(c.mask);
- error::Error error = DoStencilFillPathCHROMIUM(path, fill_mode, mask);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoStencilFillPathCHROMIUM(path, fill_mode, mask);
}
error::Error GLES2DecoderPassthroughImpl::HandleStencilStrokePathCHROMIUM(
@@ -1980,11 +1902,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleStencilStrokePathCHROMIUM(
GLuint path = static_cast<GLuint>(c.path);
GLint reference = static_cast<GLint>(c.reference);
GLuint mask = static_cast<GLuint>(c.mask);
- error::Error error = DoStencilStrokePathCHROMIUM(path, reference, mask);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoStencilStrokePathCHROMIUM(path, reference, mask);
}
error::Error GLES2DecoderPassthroughImpl::HandleCoverFillPathCHROMIUM(
@@ -1995,11 +1914,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleCoverFillPathCHROMIUM(
cmd_data);
GLuint path = static_cast<GLuint>(c.path);
GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- error::Error error = DoCoverFillPathCHROMIUM(path, cover_mode);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoCoverFillPathCHROMIUM(path, cover_mode);
}
error::Error GLES2DecoderPassthroughImpl::HandleCoverStrokePathCHROMIUM(
@@ -2010,11 +1926,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleCoverStrokePathCHROMIUM(
cmd_data);
GLuint path = static_cast<GLuint>(c.path);
GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- error::Error error = DoCoverStrokePathCHROMIUM(path, cover_mode);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoCoverStrokePathCHROMIUM(path, cover_mode);
}
error::Error
@@ -2029,12 +1942,8 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverFillPathCHROMIUM(
GLenum fill_mode = static_cast<GLenum>(c.fillMode);
GLuint mask = static_cast<GLuint>(c.mask);
GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- error::Error error =
- DoStencilThenCoverFillPathCHROMIUM(path, fill_mode, mask, cover_mode);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoStencilThenCoverFillPathCHROMIUM(path, fill_mode, mask, cover_mode);
}
error::Error
@@ -2049,12 +1958,9 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverStrokePathCHROMIUM(
GLint reference = static_cast<GLint>(c.reference);
GLuint mask = static_cast<GLuint>(c.mask);
GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- error::Error error =
- DoStencilThenCoverStrokePathCHROMIUM(path, reference, mask, cover_mode);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+
+ return DoStencilThenCoverStrokePathCHROMIUM(path, reference, mask,
+ cover_mode);
}
error::Error
@@ -2067,11 +1973,18 @@ GLES2DecoderPassthroughImpl::HandleStencilFillPathInstancedCHROMIUM(
cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLenum fill_mode = static_cast<GLenum>(c.fillMode);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2083,31 +1996,21 @@ GLES2DecoderPassthroughImpl::HandleStencilFillPathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLenum fill_mode = static_cast<GLenum>(c.fillMode);
- GLuint mask = static_cast<GLuint>(c.mask);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoStencilFillPathInstancedCHROMIUM(
+ return DoStencilFillPathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, fill_mode,
mask, transform_type, transform_values, transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error
@@ -2120,11 +2023,18 @@ GLES2DecoderPassthroughImpl::HandleStencilStrokePathInstancedCHROMIUM(
cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLint reference = static_cast<GLint>(c.reference);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2136,31 +2046,21 @@ GLES2DecoderPassthroughImpl::HandleStencilStrokePathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLint reference = static_cast<GLint>(c.reference);
- GLuint mask = static_cast<GLuint>(c.mask);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoStencilStrokePathInstancedCHROMIUM(
+ return DoStencilStrokePathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, reference,
mask, transform_type, transform_values, transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error GLES2DecoderPassthroughImpl::HandleCoverFillPathInstancedCHROMIUM(
@@ -2171,11 +2071,17 @@ error::Error GLES2DecoderPassthroughImpl::HandleCoverFillPathInstancedCHROMIUM(
cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLenum cover_mode = static_cast<GLenum>(c.coverMode);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2187,30 +2093,21 @@ error::Error GLES2DecoderPassthroughImpl::HandleCoverFillPathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoCoverFillPathInstancedCHROMIUM(
+ return DoCoverFillPathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, cover_mode,
transform_type, transform_values, transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error
@@ -2223,11 +2120,17 @@ GLES2DecoderPassthroughImpl::HandleCoverStrokePathInstancedCHROMIUM(
cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLenum cover_mode = static_cast<GLenum>(c.coverMode);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2239,30 +2142,21 @@ GLES2DecoderPassthroughImpl::HandleCoverStrokePathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoCoverStrokePathInstancedCHROMIUM(
+ return DoCoverStrokePathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, cover_mode,
transform_type, transform_values, transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error
@@ -2274,11 +2168,19 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverFillPathInstancedCHROMIUM(
StencilThenCoverFillPathInstancedCHROMIUM*>(cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLenum cover_mode = static_cast<GLenum>(c.coverMode);
+ GLenum fill_mode = static_cast<GLenum>(c.fillMode);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2290,33 +2192,22 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverFillPathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- GLenum fill_mode = static_cast<GLenum>(c.fillMode);
- GLuint mask = static_cast<GLuint>(c.mask);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoStencilThenCoverFillPathInstancedCHROMIUM(
+ return DoStencilThenCoverFillPathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, cover_mode,
fill_mode, mask, transform_type, transform_values,
transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error
@@ -2328,11 +2219,19 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverStrokePathInstancedCHROMIUM(
StencilThenCoverStrokePathInstancedCHROMIUM*>(cmd_data);
GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
GLenum path_name_type = static_cast<GLuint>(c.pathNameType);
+ GLuint path_base = static_cast<GLuint>(c.pathBase);
+ GLenum cover_mode = static_cast<GLenum>(c.coverMode);
+ GLint reference = static_cast<GLint>(c.reference);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ GLenum transform_type = static_cast<GLuint>(c.transformType);
+ uint32_t paths_shm_id = c.paths_shm_id;
+ uint32_t paths_shm_offset = c.paths_shm_offset;
+ uint32_t transform_values_shm_id = c.transformValues_shm_id;
+ uint32_t transform_values_shm_offset = c.transformValues_shm_offset;
+
const GLvoid* paths = nullptr;
GLsizei paths_bufsize = 0;
if (num_paths > 0) {
- uint32_t paths_shm_id = static_cast<uint32_t>(c.paths_shm_id);
- uint32_t paths_shm_offset = static_cast<uint32_t>(c.paths_shm_offset);
if (paths_shm_id != 0 || paths_shm_offset != 0) {
unsigned int memory_size = 0;
paths = GetSharedMemoryAndSizeAs<const GLvoid*>(
@@ -2344,33 +2243,22 @@ GLES2DecoderPassthroughImpl::HandleStencilThenCoverStrokePathInstancedCHROMIUM(
return error::kOutOfBounds;
}
}
- GLuint path_base = static_cast<GLuint>(c.pathBase);
- GLenum cover_mode = static_cast<GLenum>(c.coverMode);
- GLint reference = static_cast<GLint>(c.reference);
- GLuint mask = static_cast<GLuint>(c.mask);
- GLenum transform_type = static_cast<GLuint>(c.transformType);
const GLfloat* transform_values = nullptr;
GLsizei transform_values_bufsize = 0;
- if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) {
+ if (transform_values_shm_id != 0 || transform_values_shm_offset != 0) {
unsigned int memory_size = 0;
transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.transformValues_shm_id, c.transformValues_shm_offset, 0,
- &memory_size);
+ transform_values_shm_id, transform_values_shm_offset, 0, &memory_size);
transform_values_bufsize = static_cast<GLsizei>(memory_size);
}
if (!transform_values) {
return error::kOutOfBounds;
}
- error::Error error = DoStencilThenCoverStrokePathInstancedCHROMIUM(
+ return DoStencilThenCoverStrokePathInstancedCHROMIUM(
num_paths, path_name_type, paths, paths_bufsize, path_base, cover_mode,
reference, mask, transform_type, transform_values,
transform_values_bufsize);
- if (error != error::kNoError) {
- return error;
- }
-
- return error::kNoError;
}
error::Error
@@ -2383,7 +2271,9 @@ GLES2DecoderPassthroughImpl::HandleBindFragmentInputLocationCHROMIUMBucket(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLint location = static_cast<GLint>(c.location);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -2391,12 +2281,8 @@ GLES2DecoderPassthroughImpl::HandleBindFragmentInputLocationCHROMIUMBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- error::Error error =
- DoBindFragmentInputLocationCHROMIUM(program, location, name_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBindFragmentInputLocationCHROMIUM(program, location,
+ name_str.c_str());
}
error::Error
@@ -2411,23 +2297,22 @@ GLES2DecoderPassthroughImpl::HandleProgramPathFragmentInputGenCHROMIUM(
GLint location = static_cast<GLint>(c.location);
GLenum gen_mode = static_cast<GLint>(c.genMode);
GLint components = static_cast<GLint>(c.components);
+ uint32_t coeffs_shm_id = c.coeffs_shm_id;
+ uint32_t coeffs_shm_offset = c.coeffs_shm_offset;
+
const GLfloat* coeffs = nullptr;
GLsizei coeffs_bufsize = 0;
- if (c.coeffs_shm_id != 0 || c.coeffs_shm_offset != 0) {
+ if (coeffs_shm_id != 0 || coeffs_shm_offset != 0) {
unsigned int memory_size = 0;
coeffs = GetSharedMemoryAndSizeAs<const GLfloat*>(
- c.coeffs_shm_id, c.coeffs_shm_offset, 0, &memory_size);
+ coeffs_shm_id, coeffs_shm_offset, 0, &memory_size);
coeffs_bufsize = static_cast<GLsizei>(memory_size);
}
if (!coeffs) {
return error::kOutOfBounds;
}
- error::Error error = DoProgramPathFragmentInputGenCHROMIUM(
+ return DoProgramPathFragmentInputGenCHROMIUM(
program, location, gen_mode, components, coeffs, coeffs_bufsize);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
}
error::Error
@@ -2441,7 +2326,9 @@ GLES2DecoderPassthroughImpl::HandleBindFragDataLocationIndexedEXTBucket(
GLuint program = static_cast<GLuint>(c.program);
GLuint colorNumber = static_cast<GLuint>(c.colorNumber);
GLuint index = static_cast<GLuint>(c.index);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -2449,12 +2336,8 @@ GLES2DecoderPassthroughImpl::HandleBindFragDataLocationIndexedEXTBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- error::Error error = DoBindFragDataLocationIndexedEXT(
- program, colorNumber, index, name_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBindFragDataLocationIndexedEXT(program, colorNumber, index,
+ name_str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleBindFragDataLocationEXTBucket(
@@ -2465,7 +2348,9 @@ error::Error GLES2DecoderPassthroughImpl::HandleBindFragDataLocationEXTBucket(
cmd_data);
GLuint program = static_cast<GLuint>(c.program);
GLuint colorNumber = static_cast<GLuint>(c.colorNumber);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket || bucket->size() == 0) {
return error::kInvalidArguments;
}
@@ -2473,12 +2358,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleBindFragDataLocationEXTBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- error::Error error =
- DoBindFragDataLocationEXT(program, colorNumber, name_str.c_str());
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoBindFragDataLocationEXT(program, colorNumber, name_str.c_str());
}
error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataIndexEXT(
@@ -2487,7 +2367,11 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataIndexEXT(
const volatile gles2::cmds::GetFragDataIndexEXT& c =
*static_cast<const volatile gles2::cmds::GetFragDataIndexEXT*>(cmd_data);
GLuint program = static_cast<GLuint>(c.program);
- Bucket* bucket = GetBucket(c.name_bucket_id);
+ uint32_t index_shm_id = c.index_shm_id;
+ uint32_t index_shm_offset = c.index_shm_offset;
+ uint32_t name_bucket_id = c.name_bucket_id;
+
+ Bucket* bucket = GetBucket(name_bucket_id);
if (!bucket) {
return error::kInvalidArguments;
}
@@ -2495,8 +2379,8 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataIndexEXT(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- GLint* index = GetSharedMemoryAs<GLint*>(c.index_shm_id, c.index_shm_offset,
- sizeof(GLint));
+ GLint* index =
+ GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint));
if (!index) {
return error::kOutOfBounds;
}
@@ -2504,11 +2388,7 @@ error::Error GLES2DecoderPassthroughImpl::HandleGetFragDataIndexEXT(
if (*index != -1) {
return error::kInvalidArguments;
}
- error::Error error = DoGetFragDataIndexEXT(program, name_str.c_str(), index);
- if (error != error::kNoError) {
- return error;
- }
- return error::kNoError;
+ return DoGetFragDataIndexEXT(program, name_str.c_str(), index);
}
error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexImage2DBucket(
@@ -2521,11 +2401,13 @@ error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexImage2DBucket(
GLenum internal_format = static_cast<GLenum>(c.internalformat);
GLsizei width = static_cast<GLsizei>(c.width);
GLsizei height = static_cast<GLsizei>(c.height);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
GLint border = static_cast<GLint>(c.border);
+
Bucket* bucket = GetBucket(bucket_id);
- if (!bucket)
+ if (!bucket) {
return error::kInvalidArguments;
+ }
uint32_t image_size = bucket->size();
const void* data = bucket->GetData(0, image_size);
DCHECK(data || !image_size);
@@ -2576,10 +2458,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexSubImage2DBucket(
GLsizei width = static_cast<GLsizei>(c.width);
GLsizei height = static_cast<GLsizei>(c.height);
GLenum format = static_cast<GLenum>(c.format);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = GetBucket(bucket_id);
- if (!bucket)
+ if (!bucket) {
return error::kInvalidArguments;
+ }
uint32_t image_size = bucket->size();
const void* data = bucket->GetData(0, image_size);
DCHECK(data || !image_size);
@@ -2632,11 +2516,13 @@ error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexImage3DBucket(
GLsizei width = static_cast<GLsizei>(c.width);
GLsizei height = static_cast<GLsizei>(c.height);
GLsizei depth = static_cast<GLsizei>(c.depth);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
GLint border = static_cast<GLint>(c.border);
+
Bucket* bucket = GetBucket(bucket_id);
- if (!bucket)
+ if (!bucket) {
return error::kInvalidArguments;
+ }
GLsizei image_size = bucket->size();
const void* data = bucket->GetData(0, image_size);
DCHECK(data || !image_size);
@@ -2690,10 +2576,12 @@ error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexSubImage3DBucket(
GLsizei height = static_cast<GLsizei>(c.height);
GLsizei depth = static_cast<GLsizei>(c.depth);
GLenum format = static_cast<GLenum>(c.format);
- GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ uint32_t bucket_id = c.bucket_id;
+
Bucket* bucket = GetBucket(bucket_id);
- if (!bucket)
+ if (!bucket) {
return error::kInvalidArguments;
+ }
uint32_t image_size = bucket->size();
const void* data = bucket->GetData(0, image_size);
DCHECK(data || !image_size);
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_drawing.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_drawing.cc
new file mode 100644
index 00000000000..20f03399deb
--- /dev/null
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_drawing.cc
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_F(GLES2DecoderPassthroughTest, DrawArraysInstancedANGLEEnablement) {
+ DrawArraysInstancedANGLE cmd;
+ cmd.Init(GL_TRIANGLES, 0, 3, 1);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+
+ DoRequestExtension("GL_ANGLE_instanced_arrays");
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_F(GLES2DecoderPassthroughTest, VertexAttribDivisorANGLEEnablement) {
+ VertexAttribDivisorANGLE cmd;
+ cmd.Init(0, 1);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+
+ DoRequestExtension("GL_ANGLE_instanced_arrays");
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_F(GLES2DecoderPassthroughTest, DrawElementsInstancedANGLEEnablement) {
+ DrawElementsInstancedANGLE cmd;
+ cmd.Init(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0, 1);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+
+ DoRequestExtension("GL_ANGLE_instanced_arrays");
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_framebuffers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_framebuffers.cc
new file mode 100644
index 00000000000..c8fd6c14956
--- /dev/null
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_framebuffers.cc
@@ -0,0 +1,420 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_F(GLES3DecoderPassthroughTest, ReadPixelsBufferBound) {
+ const GLsizei kWidth = 5;
+ const GLsizei kHeight = 3;
+ const GLint kBytesPerPixel = 4;
+ GLint size = kWidth * kHeight * kBytesPerPixel;
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+
+ DoBindBuffer(GL_PIXEL_PACK_BUFFER, kClientBufferId);
+ DoBufferData(GL_PIXEL_PACK_BUFFER, size, nullptr, GL_STATIC_DRAW);
+
+ ReadPixels cmd;
+ cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
+ pixels_shm_offset, result_shm_id, result_shm_offset, false);
+ result->success = 0;
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_F(GLES3DecoderPassthroughTest, ReadPixels2PixelPackBufferNoBufferBound) {
+ const GLsizei kWidth = 5;
+ const GLsizei kHeight = 3;
+
+ ReadPixels cmd;
+ cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0, 0, false);
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_F(GLES3DecoderPassthroughTest, ReadPixels2PixelPackBuffer) {
+ const GLsizei kWidth = 5;
+ const GLsizei kHeight = 3;
+ const GLint kBytesPerPixel = 4;
+ GLint size = kWidth * kHeight * kBytesPerPixel;
+
+ DoBindBuffer(GL_PIXEL_PACK_BUFFER, kClientBufferId);
+ DoBufferData(GL_PIXEL_PACK_BUFFER, size, nullptr, GL_STATIC_DRAW);
+
+ ReadPixels cmd;
+ cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0, 0, false);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_F(GLES2DecoderPassthroughTest, DiscardFramebufferEXTUnsupported) {
+ const GLenum target = GL_FRAMEBUFFER;
+ const GLsizei count = 1;
+ const GLenum attachments[] = {GL_COLOR_EXT};
+ DiscardFramebufferEXTImmediate& cmd =
+ *GetImmediateAs<DiscardFramebufferEXTImmediate>();
+ cmd.Init(target, count, attachments);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(cmd, sizeof(attachments)));
+}
+
+TEST_F(GLES2DecoderPassthroughTest, ReadPixelsOutOfRange) {
+ const GLint kWidth = 5;
+ const GLint kHeight = 3;
+ const GLenum kFormat = GL_RGBA;
+
+ // Set up GL objects for the read pixels with a known framebuffer size
+ DoBindTexture(GL_TEXTURE_2D, kClientTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0, kFormat,
+ GL_UNSIGNED_BYTE, 0, 0);
+ DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
+ DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ kClientTextureId, 0);
+
+ // Put the resulting pixels and the result in shared memory
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+
+ uint8_t* dest = reinterpret_cast<uint8_t*>(&result[1]);
+
+ // The test cases
+ static struct {
+ GLint x, y, w, h;
+ } tests[] = {
+ {
+ -2, -1, 9, 5,
+ }, // out of range on all sides
+ {
+ 2, 1, 9, 5,
+ }, // out of range on right, bottom
+ {
+ -7, -4, 9, 5,
+ }, // out of range on left, top
+ {
+ 0, -5, 9, 5,
+ }, // completely off top
+ {
+ 0, 3, 9, 5,
+ }, // completely off bottom
+ {
+ -9, 0, 9, 5,
+ }, // completely off left
+ {
+ 5, 0, 9, 5,
+ }, // completely off right
+ };
+
+ for (auto test : tests) {
+ // Clear the readpixels buffer so that we can see which pixels have been
+ // written
+ memset(dest, 0, 4 * test.w * test.h);
+
+ ReadPixels cmd;
+ cmd.Init(test.x, test.y, test.w, test.h, kFormat, GL_UNSIGNED_BYTE,
+ pixels_shm_id, pixels_shm_offset, result_shm_id, result_shm_offset,
+ false);
+ result->success = 0;
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+ EXPECT_TRUE(result->success);
+
+ // Check the Result has the correct metadata for what was read.
+ GLint startx = std::max(test.x, 0);
+ GLint endx = std::min(test.x + test.w, kWidth);
+ EXPECT_EQ(result->row_length, endx - startx);
+
+ GLint starty = std::max(test.y, 0);
+ GLint endy = std::min(test.y + test.h, kHeight);
+ EXPECT_EQ(result->num_rows, endy - starty);
+
+ // Check each pixel and expect them to be non-zero if they were written. The
+ // non-zero values are written by ANGLE's NULL backend to simulate the
+ // memory that would be modified by the call.
+ for (GLint dx = 0; dx < test.w; ++dx) {
+ GLint x = test.x + dx;
+ for (GLint dy = 0; dy < test.h; ++dy) {
+ GLint y = test.y + dy;
+
+ bool expect_written = 0 <= x && x < kWidth && 0 <= y && y < kHeight;
+ for (GLint component = 0; component < 4; ++component) {
+ uint8_t value = dest[4 * (dy * test.w + dx) + component];
+ EXPECT_EQ(expect_written, value != 0)
+ << x << " " << y << " " << value;
+ }
+ }
+ }
+ }
+}
+
+TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsync) {
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ const GLsizei kWidth = 4;
+ const GLsizei kHeight = 4;
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+
+ ReadPixels read_pixels_cmd;
+ read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels_shm_id, pixels_shm_offset, result_shm_id,
+ result_shm_offset, true);
+ result->success = 0;
+
+ EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());
+
+ {
+ // Verify internals of pending read pixels
+ const auto& all_pending_read_pixels = GetPendingReadPixels();
+ EXPECT_EQ(1u, all_pending_read_pixels.size());
+
+ const auto& pending_read_pixels = all_pending_read_pixels.front();
+ EXPECT_NE(nullptr, pending_read_pixels.fence);
+ EXPECT_EQ(pixels_shm_id, pending_read_pixels.pixels_shm_id);
+ EXPECT_EQ(pixels_shm_offset, pending_read_pixels.pixels_shm_offset);
+ EXPECT_EQ(result_shm_offset, pending_read_pixels.result_shm_offset);
+ EXPECT_EQ(result_shm_id, pending_read_pixels.result_shm_id);
+ EXPECT_NE(0u, pending_read_pixels.buffer_service_id);
+ EXPECT_TRUE(pending_read_pixels.waiting_async_pack_queries.empty());
+ }
+
+ Finish finish_cmd;
+ finish_cmd.Init();
+ EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
+ EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
+ EXPECT_TRUE(GetPendingReadPixels().empty());
+}
+
+TEST_F(GLES3DecoderPassthroughTest, ReadPixelsAsyncSkippedIfPBOBound) {
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ const GLsizei kWidth = 4;
+ const GLsizei kHeight = 4;
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+
+ cmds::BindBuffer bind_cmd;
+ bind_cmd.Init(GL_PIXEL_PACK_BUFFER, kClientBufferId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(bind_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ cmds::BufferData buffer_data_cmd;
+ size_t read_pixels_result_size = kWidth * kHeight * 4;
+ buffer_data_cmd.Init(GL_PIXEL_PACK_BUFFER, read_pixels_result_size, 0, 0,
+ GL_STREAM_DRAW);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(buffer_data_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ // Check that there is no idle work to do when a PBO is already bound and that
+ // the ReadPixel succeeded
+ ReadPixels read_pixels_cmd;
+ read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0,
+ result_shm_id, result_shm_offset, true);
+ result->success = 0;
+ EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
+}
+
+TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncModifyCommand) {
+ typedef ReadPixels::Result Result;
+ size_t shm_size = 0;
+ Result* result = GetSharedMemoryAsWithSize<Result*>(&shm_size);
+ const GLsizei kWidth = 4;
+ const GLsizei kHeight = 4;
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+
+ size_t pixels_memory_size = shm_size - 1;
+ char* pixels = reinterpret_cast<char*>(result + 1);
+
+ constexpr char kDummyValue = 11;
+ size_t read_pixels_result_size = kWidth * kHeight * 4;
+ EXPECT_GT(pixels_memory_size, read_pixels_result_size);
+ memset(pixels, kDummyValue, pixels_memory_size);
+
+ ReadPixels read_pixels_cmd;
+ read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels_shm_id, pixels_shm_offset, result_shm_id,
+ result_shm_offset, true);
+ result->success = 0;
+
+ EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());
+
+ // Change command after ReadPixels issued, but before we finish the read,
+ // should have no impact.
+ read_pixels_cmd.Init(1, 2, 6, 7, GL_RGB, GL_UNSIGNED_SHORT, pixels_shm_id,
+ pixels_shm_offset, result_shm_id, result_shm_offset,
+ false);
+
+ Finish finish_cmd;
+ finish_cmd.Init();
+ EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
+ EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
+ EXPECT_TRUE(GetPendingReadPixels().empty());
+
+ // Validate that only the correct bytes of pixels have been written to.
+ for (size_t i = 0; i < pixels_memory_size; i++) {
+ // ANGLE's null context always returns 42 for all pixel bytes for ReadPixels
+ // calls.
+ constexpr char kReadPixelsValue = 42;
+ char expected_value =
+ i < read_pixels_result_size ? kReadPixelsValue : kDummyValue;
+ EXPECT_EQ(expected_value, pixels[i]);
+ }
+}
+
+TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncChangePackAlignment) {
+ typedef ReadPixels::Result Result;
+ size_t shm_size = 0;
+ Result* result = GetSharedMemoryAsWithSize<Result*>(&shm_size);
+ const GLsizei kWidth = 4;
+ const GLsizei kHeight = 4;
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+
+ size_t pixels_memory_size = shm_size - 1;
+ char* pixels = reinterpret_cast<char*>(result + 1);
+
+ constexpr char kDummyValue = 11;
+ size_t read_pixels_result_size = kWidth * kHeight * 4;
+ EXPECT_GT(pixels_memory_size, read_pixels_result_size);
+ memset(pixels, kDummyValue, pixels_memory_size);
+
+ ReadPixels read_pixels_cmd;
+ read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels_shm_id, pixels_shm_offset, result_shm_id,
+ result_shm_offset, true);
+ result->success = 0;
+
+ EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());
+
+ PixelStorei pixel_store_i_cmd;
+ pixel_store_i_cmd.Init(GL_PACK_ALIGNMENT, 8);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(pixel_store_i_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ Finish finish_cmd;
+ finish_cmd.Init();
+ EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
+ EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
+ EXPECT_TRUE(GetPendingReadPixels().empty());
+
+ // Validate that only the correct bytes of pixels have been written to.
+ for (size_t i = 0; i < pixels_memory_size; i++) {
+ // ANGLE's null context always returns 42 for all pixel bytes for ReadPixels
+ // calls.
+ constexpr char kReadPixelsValue = 42;
+ char expected_value =
+ i < read_pixels_result_size ? kReadPixelsValue : kDummyValue;
+ EXPECT_EQ(expected_value, pixels[i]);
+ }
+}
+
+TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncError) {
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ const GLsizei kWidth = 4;
+ const GLsizei kHeight = 4;
+ uint32_t result_shm_id = shared_memory_id_;
+ uint32_t result_shm_offset = kSharedMemoryOffset;
+ uint32_t pixels_shm_id = shared_memory_id_;
+ uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+
+ // Inject an INVALID_OPERATION error on the call to ReadPixels
+ InjectGLError(GL_NO_ERROR);
+ InjectGLError(GL_INVALID_OPERATION);
+
+ ReadPixels cmd;
+ cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
+ pixels_shm_offset, result_shm_id, result_shm_offset, true);
+ result->success = 0;
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+ EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
+ EXPECT_TRUE(GetPendingReadPixels().empty());
+}
+
+TEST_F(GLES2DecoderPassthroughTest,
+ RenderbufferStorageMultisampleEXTNotSupported) {
+ DoBindRenderbuffer(GL_RENDERBUFFER, kClientRenderbufferId);
+ // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM.
+ RenderbufferStorageMultisampleEXT cmd;
+ cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 1, 1);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_F(GLES2DecoderPassthroughTest,
+ GetFramebufferAttachmentParameterivWithRenderbuffer) {
+ DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
+ DoBindRenderbuffer(GL_RENDERBUFFER, kClientRenderbufferId);
+ DoFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, kClientRenderbufferId);
+
+ GetFramebufferAttachmentParameteriv::Result* result =
+ static_cast<GetFramebufferAttachmentParameteriv::Result*>(
+ shared_memory_address_);
+ result->size = 0;
+ const GLint* result_value = result->GetData();
+
+ GetFramebufferAttachmentParameteriv cmd;
+ cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(kClientRenderbufferId, static_cast<GLuint>(*result_value));
+}
+
+TEST_F(GLES2DecoderPassthroughTest,
+ GetFramebufferAttachmentParameterivWithTexture) {
+ DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
+ DoBindTexture(GL_TEXTURE_2D, kClientTextureId);
+ DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ kClientTextureId, 0);
+
+ GetFramebufferAttachmentParameteriv::Result* result =
+ static_cast<GetFramebufferAttachmentParameteriv::Result*>(
+ shared_memory_address_);
+ result->size = 0;
+ const GLint* result_value = result->GetData();
+
+ GetFramebufferAttachmentParameteriv cmd;
+ cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(kClientTextureId, static_cast<GLuint>(*result_value));
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 0c39b3be25b..5fdc10d2d44 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -18,6 +18,7 @@
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/program_manager.h"
@@ -242,7 +243,8 @@ void GLES2DecoderTestBase::InitDecoderWithWorkarounds(
// we can use the ContextGroup to figure out how the real GLES2Decoder
// will initialize itself.
command_buffer_service_.reset(new FakeCommandBufferServiceBase());
- mock_decoder_.reset(new MockGLES2Decoder(command_buffer_service_.get()));
+ mock_decoder_.reset(
+ new MockGLES2Decoder(command_buffer_service_.get(), &outputter_));
EXPECT_TRUE(group_->Initialize(mock_decoder_.get(), init.context_type,
DisallowedFeatures()));
@@ -484,8 +486,8 @@ void GLES2DecoderTestBase::InitDecoderWithWorkarounds(
normalized_init.lose_context_when_out_of_memory;
attribs.context_type = init.context_type;
- decoder_.reset(
- GLES2Decoder::Create(this, command_buffer_service_.get(), group_.get()));
+ decoder_.reset(GLES2Decoder::Create(this, command_buffer_service_.get(),
+ &outputter_, group_.get()));
decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
ASSERT_TRUE(decoder_->Initialize(surface_, context_, false,
@@ -2270,7 +2272,7 @@ void GLES2DecoderPassthroughTestBase::SetUp() {
command_buffer_service_.reset(new FakeCommandBufferServiceBase());
decoder_.reset(new GLES2DecoderPassthroughImpl(
- this, command_buffer_service_.get(), group_.get()));
+ this, command_buffer_service_.get(), &outputter_, group_.get()));
ASSERT_TRUE(group_->Initialize(decoder_.get(),
context_creation_attribs_.context_type,
DisallowedFeatures()));
@@ -2285,6 +2287,7 @@ void GLES2DecoderPassthroughTestBase::SetUp() {
shared_memory_address_ =
reinterpret_cast<int8_t*>(buffer->memory()) + shared_memory_offset_;
shared_memory_base_ = buffer->memory();
+ shared_memory_size_ = kSharedBufferSize - shared_memory_offset_;
decoder_->MakeCurrent();
decoder_->BeginDecoding();
@@ -2302,6 +2305,25 @@ void GLES2DecoderPassthroughTestBase::TearDown() {
gl::init::ShutdownGL();
}
+void GLES2DecoderPassthroughTestBase::SetBucketData(uint32_t bucket_id,
+ const void* data,
+ size_t data_size) {
+ DCHECK(data || data_size == 0);
+ {
+ cmd::SetBucketSize cmd;
+ cmd.Init(bucket_id, static_cast<uint32_t>(data_size));
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+ if (data) {
+ memcpy(shared_memory_address_, data, data_size);
+ cmd::SetBucketData cmd;
+ cmd.Init(bucket_id, 0, static_cast<uint32_t>(data_size), shared_memory_id_,
+ kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ memset(shared_memory_address_, 0, data_size);
+ }
+}
+
GLint GLES2DecoderPassthroughTestBase::GetGLError() {
cmds::GetError cmd;
cmd.Init(shared_memory_id_, shared_memory_offset_);
@@ -2309,6 +2331,22 @@ GLint GLES2DecoderPassthroughTestBase::GetGLError() {
return static_cast<GLint>(*GetSharedMemoryAs<GLenum*>());
}
+void GLES2DecoderPassthroughTestBase::InjectGLError(GLenum error) {
+ decoder_->InjectDriverError(error);
+}
+
+void GLES2DecoderPassthroughTestBase::DoRequestExtension(
+ const char* extension) {
+ DCHECK(extension != nullptr);
+
+ uint32_t bucket_id = 0;
+ SetBucketData(bucket_id, extension, strlen(extension) + 1);
+
+ cmds::RequestExtensionCHROMIUM cmd;
+ cmd.Init(bucket_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
void GLES2DecoderPassthroughTestBase::DoBindBuffer(GLenum target,
GLuint client_id) {
cmds::BindBuffer cmd;
@@ -2347,6 +2385,65 @@ void GLES2DecoderPassthroughTestBase::DoBufferSubData(GLenum target,
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
+void GLES2DecoderPassthroughTestBase::DoBindTexture(GLenum target,
+ GLuint client_id) {
+ cmds::BindTexture cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderPassthroughTestBase::DoTexImage2D(
+ GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ uint32_t shared_memory_id,
+ uint32_t shared_memory_offset) {
+ cmds::TexImage2D cmd;
+ cmd.Init(target, level, internal_format, width, height, format, type,
+ shared_memory_id, shared_memory_offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderPassthroughTestBase::DoBindFramebuffer(GLenum target,
+ GLuint client_id) {
+ cmds::BindFramebuffer cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderPassthroughTestBase::DoFramebufferTexture2D(
+ GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture_client_id,
+ GLint level) {
+ cmds::FramebufferTexture2D cmd;
+ cmd.Init(target, attachment, textarget, texture_client_id, level);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderPassthroughTestBase::DoFramebufferRenderbuffer(
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer) {
+ cmds::FramebufferRenderbuffer cmd;
+ cmd.Init(target, attachment, renderbuffertarget, renderbuffer);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderPassthroughTestBase::DoBindRenderbuffer(GLenum target,
+ GLuint client_id) {
+ cmds::BindRenderbuffer cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const size_t GLES2DecoderPassthroughTestBase::kSharedBufferSize;
@@ -2356,6 +2453,9 @@ const int32_t GLES2DecoderPassthroughTestBase::kInvalidSharedMemoryId;
const uint32_t GLES2DecoderPassthroughTestBase::kNewClientId;
const GLuint GLES2DecoderPassthroughTestBase::kClientBufferId;
+const GLuint GLES2DecoderPassthroughTestBase::kClientTextureId;
+const GLuint GLES2DecoderPassthroughTestBase::kClientFramebufferId;
+const GLuint GLES2DecoderPassthroughTestBase::kClientRenderbufferId;
#endif
} // namespace gles2
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index adcef8523f6..ff7f6cf6092 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -23,6 +23,7 @@
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/program_manager.h"
@@ -668,6 +669,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool>,
scoped_refptr<gl::GLSurfaceStub> surface_;
scoped_refptr<GLContextMock> context_;
std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
+ TraceOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> mock_decoder_;
std::unique_ptr<GLES2Decoder> decoder_;
MemoryTracker* memory_tracker_;
@@ -859,24 +861,54 @@ class GLES2DecoderPassthroughTestBase : public testing::Test,
&entries_processed);
}
+ void SetBucketData(uint32_t bucket_id, const void* data, size_t data_size);
+
template <typename T>
T GetSharedMemoryAs() {
return reinterpret_cast<T>(shared_memory_address_);
}
template <typename T>
+ T GetSharedMemoryAsWithSize(size_t* out_shmem_size) {
+ *out_shmem_size = shared_memory_size_;
+ return reinterpret_cast<T>(shared_memory_address_);
+ }
+
+ template <typename T>
T GetSharedMemoryAsWithOffset(uint32_t offset) {
void* ptr = reinterpret_cast<int8_t*>(shared_memory_address_) + offset;
return reinterpret_cast<T>(ptr);
}
+ template <typename T>
+ T GetSharedMemoryAsWithOffsetAndSize(uint32_t offset,
+ size_t* out_shmem_size) {
+ EXPECT_LT(offset, shared_memory_size_);
+ *out_shmem_size = shared_memory_size_ - offset;
+ void* ptr = reinterpret_cast<int8_t*>(shared_memory_address_) + offset;
+ return reinterpret_cast<T>(ptr);
+ }
+
+ template <typename T>
+ T* GetImmediateAs() {
+ return reinterpret_cast<T*>(immediate_buffer_);
+ }
+
+ GLES2DecoderPassthroughImpl* GetDecoder() const { return decoder_.get(); }
PassthroughResources* GetPassthroughResources() const {
return group_->passthrough_resources();
}
+ const base::circular_deque<GLES2DecoderPassthroughImpl::PendingReadPixels>&
+ GetPendingReadPixels() const {
+ return decoder_->pending_read_pixels_;
+ }
GLint GetGLError();
+ void InjectGLError(GLenum error);
protected:
+ void DoRequestExtension(const char* extension);
+
void DoBindBuffer(GLenum target, GLuint client_id);
void DoDeleteBuffer(GLuint client_id);
void DoBufferData(GLenum target,
@@ -888,6 +920,31 @@ class GLES2DecoderPassthroughTestBase : public testing::Test,
GLsizeiptr size,
const void* data);
+ void DoBindTexture(GLenum target, GLuint client_id);
+ void DoTexImage2D(GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ uint32_t shared_memory_id,
+ uint32_t shared_memory_offset);
+
+ void DoBindFramebuffer(GLenum target, GLuint client_id);
+ void DoFramebufferTexture2D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture_client_id,
+ GLint level);
+ void DoFramebufferRenderbuffer(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+
+ void DoBindRenderbuffer(GLenum target, GLuint client_id);
+
static const size_t kSharedBufferSize = 2048;
static const uint32_t kSharedMemoryOffset = 132;
static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
@@ -896,11 +953,17 @@ class GLES2DecoderPassthroughTestBase : public testing::Test,
static const uint32_t kNewClientId = 501;
static const GLuint kClientBufferId = 100;
+ static const GLuint kClientTextureId = 101;
+ static const GLuint kClientFramebufferId = 102;
+ static const GLuint kClientRenderbufferId = 103;
int32_t shared_memory_id_;
uint32_t shared_memory_offset_;
void* shared_memory_address_;
void* shared_memory_base_;
+ size_t shared_memory_size_;
+
+ uint32_t immediate_buffer_[64];
private:
ContextCreationAttribHelper context_creation_attribs_;
@@ -914,6 +977,7 @@ class GLES2DecoderPassthroughTestBase : public testing::Test,
scoped_refptr<gl::GLSurface> surface_;
scoped_refptr<gl::GLContext> context_;
std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
+ TraceOutputter outputter_;
std::unique_ptr<GLES2DecoderPassthroughImpl> decoder_;
scoped_refptr<ContextGroup> group_;
};
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 7524122ad36..99289d7a411 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -4041,8 +4041,10 @@ TEST_P(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) {
init.gl_version = "opengl es 3.0";
InitDecoder(init);
DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
- DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
- DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0,
+ GL_RGBA, GL_FLOAT, 0, 0, GL_RGBA32F);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB,
+ GL_FLOAT, 0, 0, GL_RGB32F);
DoTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
DoTexImage2D(
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index c5b581a826a..94e56da1f65 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -1211,6 +1211,7 @@ static const GLenum
GL_RGB_YCRCB_420_CHROMIUM,
GL_RGB_YCBCR_422_CHROMIUM,
GL_RGB_YCBCR_420V_CHROMIUM,
+ GL_R16_EXT,
};
bool Validators::TextureSrgbDecodeExtValidator::IsValid(
diff --git a/chromium/gpu/command_buffer/service/gpu_preferences.h b/chromium/gpu/command_buffer/service/gpu_preferences.h
index 8dd0ff114ea..b37c2cc70ec 100644
--- a/chromium/gpu/command_buffer/service/gpu_preferences.h
+++ b/chromium/gpu/command_buffer/service/gpu_preferences.h
@@ -141,9 +141,6 @@ struct GPU_EXPORT GpuPreferences {
// Turns on calling TRACE for every GL call.
bool enable_gpu_service_tracing = false;
- // Enable OpenGL ES 3 APIs.
- bool enable_es3_apis = true;
-
// Use the Pass-through command decoder, skipping all validation and state
// tracking.
bool use_passthrough_cmd_decoder = false;
diff --git a/chromium/gpu/command_buffer/service/gpu_switches.cc b/chromium/gpu/command_buffer/service/gpu_switches.cc
index 50ff573a5cf..21f51cb1d4b 100644
--- a/chromium/gpu/command_buffer/service/gpu_switches.cc
+++ b/chromium/gpu/command_buffer/service/gpu_switches.cc
@@ -62,4 +62,8 @@ const char kGLShaderIntermOutput[] = "gl-shader-interm-output";
// round intermediate values in ANGLE.
const char kEmulateShaderPrecision[] = "emulate-shader-precision";
+// Use the Pass-through command decoder, skipping all validation and state
+// tracking.
+const char kUsePassthroughCmdDecoder[] = "use-passthrough-cmd-decoder";
+
} // namespace switches
diff --git a/chromium/gpu/command_buffer/service/gpu_switches.h b/chromium/gpu/command_buffer/service/gpu_switches.h
index f1a75801430..ef27cc7b4a2 100644
--- a/chromium/gpu/command_buffer/service/gpu_switches.h
+++ b/chromium/gpu/command_buffer/service/gpu_switches.h
@@ -28,6 +28,7 @@ GPU_EXPORT extern const char kDisableGpuShaderDiskCache[];
GPU_EXPORT extern const char kEnableThreadedTextureMailboxes[];
GPU_EXPORT extern const char kGLShaderIntermOutput[];
GPU_EXPORT extern const char kEmulateShaderPrecision[];
+GPU_EXPORT extern const char kUsePassthroughCmdDecoder[];
} // namespace switches
diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.cc b/chromium/gpu/command_buffer/service/gpu_tracer.cc
index 960dcdf65b3..e3f8f631e60 100644
--- a/chromium/gpu/command_buffer/service/gpu_tracer.cc
+++ b/chromium/gpu/command_buffer/service/gpu_tracer.cc
@@ -7,8 +7,6 @@
#include <stddef.h>
#include <stdint.h>
-#include <deque>
-
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
@@ -35,8 +33,6 @@ constexpr const char* kGpuTraceSourceNames[] = {
static_assert(NUM_TRACER_SOURCES == arraysize(kGpuTraceSourceNames),
"Trace source names must match enumeration.");
-static TraceOutputter* g_outputter_thread = NULL;
-
TraceMarker::TraceMarker(const std::string& category, const std::string& name)
: category_(category),
name_(name),
@@ -45,23 +41,16 @@ TraceMarker::TraceMarker(const std::string& category, const std::string& name)
TraceMarker::TraceMarker(const TraceMarker& other) = default;
-TraceMarker::~TraceMarker() {
-}
+TraceMarker::~TraceMarker() {}
-scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) {
- if (!g_outputter_thread) {
- g_outputter_thread = new TraceOutputter(name);
- }
- return g_outputter_thread;
-}
+TraceOutputter::TraceOutputter() : named_thread_("Dummy Trace") {}
-TraceOutputter::TraceOutputter(const std::string& name)
- : named_thread_(name.c_str()) {
+TraceOutputter::TraceOutputter(const std::string& name) : named_thread_(name) {
named_thread_.Start();
named_thread_.Stop();
}
-TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; }
+TraceOutputter::~TraceOutputter() {}
void TraceOutputter::TraceDevice(GpuTracerSource source,
const std::string& category,
@@ -124,7 +113,7 @@ void TraceOutputter::TraceServiceEnd(GpuTracerSource source,
"channel", kGpuTraceSourceNames[source]);
}
-GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
+GPUTrace::GPUTrace(Outputter* outputter,
gl::GPUTimingClient* gpu_timing_client,
const GpuTracerSource source,
const std::string& category,
@@ -141,8 +130,7 @@ GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
gpu_timer_ = gpu_timing_client->CreateGPUTimer(false);
}
-GPUTrace::~GPUTrace() {
-}
+GPUTrace::~GPUTrace() {}
void GPUTrace::Destroy(bool have_context) {
if (gpu_timer_.get()) {
@@ -183,7 +171,7 @@ void GPUTrace::Process() {
}
}
-GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
+GPUTracer::GPUTracer(GLES2Decoder* decoder)
: gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
TRACE_DISABLED_BY_DEFAULT("gpu.service"))),
gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
@@ -191,17 +179,16 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
decoder_(decoder) {
DCHECK(decoder_);
gl::GLContext* context = decoder_->GetGLContext();
- if (context) {
+ if (context)
gpu_timing_client_ = context->CreateGPUTimingClient();
- } else {
+ else
gpu_timing_client_ = new gl::GPUTimingClient();
- }
+ outputter_ = decoder_->outputter();
disjoint_time_ = gpu_timing_client_->GetCurrentCPUTime();
}
-GPUTracer::~GPUTracer() {
-}
+GPUTracer::~GPUTracer() {}
void GPUTracer::Destroy(bool have_context) {
ClearOngoingTraces(have_context);
@@ -213,10 +200,6 @@ bool GPUTracer::BeginDecoding() {
gpu_executing_ = true;
if (IsTracing()) {
- if (!outputter_) {
- outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName());
- }
-
CheckDisjointStatus();
// Begin a Trace for all active markers
for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
@@ -271,10 +254,6 @@ bool GPUTracer::Begin(const std::string& category, const std::string& name,
// Push new marker from given 'source'
markers_[source].push_back(TraceMarker(category, name));
- if (!outputter_) {
- outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName());
- }
-
// Create trace
if (IsTracing()) {
began_device_traces_ |= (*gpu_trace_dev_category != 0);
@@ -380,10 +359,6 @@ const std::string& GPUTracer::CurrentName(GpuTracerSource source) const {
return base::EmptyString();
}
-scoped_refptr<Outputter> GPUTracer::CreateOutputter(const std::string& name) {
- return TraceOutputter::Create(name);
-}
-
bool GPUTracer::CheckDisjointStatus() {
const int64_t current_time = gpu_timing_client_->GetCurrentCPUTime();
if (*gpu_trace_dev_category == 0)
diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.h b/chromium/gpu/command_buffer/service/gpu_tracer.h
index 746ebd08f7e..654c64c88ee 100644
--- a/chromium/gpu/command_buffer/service/gpu_tracer.h
+++ b/chromium/gpu/command_buffer/service/gpu_tracer.h
@@ -8,12 +8,12 @@
#include <stdint.h>
-#include <deque>
#include <memory>
-#include <stack>
#include <string>
#include <vector>
+#include "base/containers/circular_deque.h"
+#include "base/containers/stack.h"
#include "base/macros.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
@@ -55,7 +55,7 @@ struct TraceMarker {
// Traces GPU Commands.
class GPU_EXPORT GPUTracer {
public:
- explicit GPUTracer(gles2::GLES2Decoder* decoder);
+ explicit GPUTracer(GLES2Decoder* decoder);
virtual ~GPUTracer();
void Destroy(bool have_context);
@@ -84,31 +84,29 @@ class GPU_EXPORT GPUTracer {
const std::string& CurrentName(GpuTracerSource source) const;
protected:
- // Trace Processing.
- virtual scoped_refptr<Outputter> CreateOutputter(const std::string& name);
+ scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
+ const unsigned char* gpu_trace_srv_category;
+ const unsigned char* gpu_trace_dev_category;
+ private:
bool CheckDisjointStatus();
void ClearOngoingTraces(bool have_context);
- scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
- scoped_refptr<Outputter> outputter_;
+ Outputter* outputter_ = nullptr;
std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES];
- std::deque<scoped_refptr<GPUTrace> > finished_traces_;
-
- const unsigned char* gpu_trace_srv_category;
- const unsigned char* gpu_trace_dev_category;
- gles2::GLES2Decoder* decoder_;
+ base::circular_deque<scoped_refptr<GPUTrace>> finished_traces_;
+ GLES2Decoder* decoder_;
int64_t disjoint_time_ = 0;
-
bool gpu_executing_ = false;
bool began_device_traces_ = false;
- private:
DISALLOW_COPY_AND_ASSIGN(GPUTracer);
};
-class Outputter : public base::RefCounted<Outputter> {
+class GPU_EXPORT Outputter {
public:
+ virtual ~Outputter() {}
+
virtual void TraceDevice(GpuTracerSource source,
const std::string& category,
const std::string& name,
@@ -122,15 +120,14 @@ class Outputter : public base::RefCounted<Outputter> {
virtual void TraceServiceEnd(GpuTracerSource source,
const std::string& category,
const std::string& name) = 0;
-
- protected:
- virtual ~Outputter() {}
- friend class base::RefCounted<Outputter>;
};
-class TraceOutputter : public Outputter {
+class GPU_EXPORT TraceOutputter : public Outputter {
public:
- static scoped_refptr<TraceOutputter> Create(const std::string& name);
+ TraceOutputter();
+ explicit TraceOutputter(const std::string& name);
+ ~TraceOutputter() override;
+
void TraceDevice(GpuTracerSource source,
const std::string& category,
const std::string& name,
@@ -145,25 +142,20 @@ class TraceOutputter : public Outputter {
const std::string& category,
const std::string& name) override;
- protected:
- friend class base::RefCounted<Outputter>;
- explicit TraceOutputter(const std::string& name);
- ~TraceOutputter() override;
-
+ private:
base::Thread named_thread_;
uint64_t local_trace_device_id_ = 0;
uint64_t local_trace_service_id_ = 0;
- std::stack<uint64_t> trace_service_id_stack_[NUM_TRACER_SOURCES];
+ base::stack<uint64_t> trace_service_id_stack_[NUM_TRACER_SOURCES];
- private:
DISALLOW_COPY_AND_ASSIGN(TraceOutputter);
};
class GPU_EXPORT GPUTrace
: public base::RefCounted<GPUTrace> {
public:
- GPUTrace(scoped_refptr<Outputter> outputter,
+ GPUTrace(Outputter* outputter,
gl::GPUTimingClient* gpu_timing_client,
const GpuTracerSource source,
const std::string& category,
@@ -190,7 +182,7 @@ class GPU_EXPORT GPUTrace
const GpuTracerSource source_ = kTraceGroupInvalid;
const std::string category_;
const std::string name_;
- scoped_refptr<Outputter> outputter_;
+ Outputter* outputter_ = nullptr;
std::unique_ptr<gl::GPUTimer> gpu_timer_;
const bool service_enabled_ = false;
const bool device_enabled_ = false;
diff --git a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc
index ac2ab7b5101..1b00d6c7597 100644
--- a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc
+++ b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc
@@ -5,6 +5,7 @@
#include <stdint.h>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
@@ -33,28 +34,25 @@ int64_t FakeCpuTime() {
class MockOutputter : public Outputter {
public:
MockOutputter() {}
+ ~MockOutputter() override {}
+
MOCK_METHOD5(TraceDevice,
void(GpuTracerSource source,
const std::string& category,
const std::string& name,
int64_t start_time,
int64_t end_time));
-
MOCK_METHOD3(TraceServiceBegin,
void(GpuTracerSource source,
const std::string& category, const std::string& name));
-
MOCK_METHOD3(TraceServiceEnd,
void(GpuTracerSource source,
const std::string& category, const std::string& name));
-
- protected:
- ~MockOutputter() {}
};
class GPUTracerTester : public GPUTracer {
public:
- explicit GPUTracerTester(gles2::GLES2Decoder* decoder)
+ explicit GPUTracerTester(GLES2Decoder* decoder)
: GPUTracer(decoder), tracing_enabled_(0) {
gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
@@ -69,20 +67,8 @@ class GPUTracerTester : public GPUTracer {
tracing_enabled_ = enabled ? 1 : 0;
}
- void SetOutputter(scoped_refptr<Outputter> outputter) {
- set_outputter_ = outputter;
- }
-
- protected:
- scoped_refptr<Outputter> CreateOutputter(const std::string& name) override {
- if (set_outputter_.get()) {
- return set_outputter_;
- }
- return new MockOutputter();
- }
-
+ private:
unsigned char tracing_enabled_;
- scoped_refptr<Outputter> set_outputter_;
};
class BaseGpuTest : public GpuServiceTest {
@@ -117,14 +103,10 @@ class BaseGpuTest : public GpuServiceTest {
gpu_timing_client_ = GetGLContext()->CreateGPUTimingClient();
gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
gl_fake_queries_.Reset();
-
- outputter_ref_ = new MockOutputter();
}
void TearDown() override {
- outputter_ref_ = NULL;
gpu_timing_client_ = NULL;
-
gl_fake_queries_.Reset();
GpuServiceTest::TearDown();
}
@@ -216,7 +198,7 @@ class BaseGpuTest : public GpuServiceTest {
gl::GPUTimingFake gl_fake_queries_;
scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
- scoped_refptr<MockOutputter> outputter_ref_;
+ MockOutputter outputter_;
};
// Test GPUTrace calls all the correct gl calls.
@@ -239,7 +221,7 @@ class BaseGpuTraceTest : public BaseGpuTest {
const int64_t expect_end_time =
(end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
- ExpectOutputterMocks(outputter_ref_.get(), tracing_service, tracing_device,
+ ExpectOutputterMocks(&outputter_, tracing_service, tracing_device,
tracer_source, category_name, trace_name,
expect_start_time, expect_end_time);
@@ -247,8 +229,8 @@ class BaseGpuTraceTest : public BaseGpuTest {
ExpectTraceQueryMocks();
scoped_refptr<GPUTrace> trace = new GPUTrace(
- outputter_ref_, gpu_timing_client_.get(), tracer_source,
- category_name, trace_name, tracing_service, tracing_device);
+ &outputter_, gpu_timing_client_.get(), tracer_source, category_name,
+ trace_name, tracing_service, tracing_device);
gl_fake_queries_.SetCurrentGLTime(start_timestamp);
g_fakeCPUTime = expect_start_time;
@@ -279,8 +261,6 @@ class BaseGpuTraceTest : public BaseGpuTest {
// Destroy trace after we are done.
trace->Destroy(true);
-
- outputter_ref_ = NULL;
}
};
@@ -337,17 +317,14 @@ class BaseGpuTracerTest : public BaseGpuTest {
ExpectTracerOffsetQueryMocks();
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
GPUTracerTester tracer(&decoder);
tracer.SetTracingEnabled(true);
- tracer.SetOutputter(outputter_ref_);
-
ASSERT_TRUE(tracer.BeginDecoding());
ASSERT_TRUE(tracer.EndDecoding());
-
- outputter_ref_ = NULL;
}
void DoDisabledTracingTest() {
@@ -356,11 +333,11 @@ class BaseGpuTracerTest : public BaseGpuTest {
const GpuTracerSource source = static_cast<GpuTracerSource>(0);
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
GPUTracerTester tracer(&decoder);
tracer.SetTracingEnabled(false);
- tracer.SetOutputter(outputter_ref_);
ASSERT_TRUE(tracer.BeginDecoding());
ASSERT_TRUE(tracer.Begin("disabled_category", "disabled_name", source));
@@ -384,13 +361,12 @@ class BaseGpuTracerTest : public BaseGpuTest {
(end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
GPUTracerTester tracer(&decoder);
tracer.SetTracingEnabled(true);
- tracer.SetOutputter(outputter_ref_);
-
gl_fake_queries_.SetCurrentGLTime(start_timestamp);
g_fakeCPUTime = expect_start_time;
@@ -412,8 +388,8 @@ class BaseGpuTracerTest : public BaseGpuTest {
std::string source_trace_name = trace_name + num_char;
const GpuTracerSource source = static_cast<GpuTracerSource>(i);
- ExpectOutputterBeginMocks(outputter_ref_.get(), source,
- source_category, source_trace_name);
+ ExpectOutputterBeginMocks(&outputter, source, source_category,
+ source_trace_name);
ASSERT_TRUE(tracer.Begin(source_category, source_trace_name, source));
}
for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
@@ -430,7 +406,7 @@ class BaseGpuTracerTest : public BaseGpuTest {
const bool valid_timer = gpu_timing_client_->IsAvailable();
const GpuTracerSource source = static_cast<GpuTracerSource>(i);
- ExpectOutputterEndMocks(outputter_ref_.get(), source, source_category,
+ ExpectOutputterEndMocks(&outputter, source, source_category,
source_trace_name, expect_start_time + i,
expect_end_time + i, true, valid_timer);
// Check if the current category/name are correct for this source.
@@ -441,7 +417,6 @@ class BaseGpuTracerTest : public BaseGpuTest {
}
ASSERT_TRUE(tracer.EndDecoding());
tracer.ProcessTraces();
- outputter_ref_ = NULL;
}
void DoOngoingTracerMarkerTest() {
@@ -459,10 +434,10 @@ class BaseGpuTracerTest : public BaseGpuTest {
const bool valid_timer = gpu_timing_client_->IsAvailable();
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
GPUTracerTester tracer(&decoder);
- tracer.SetOutputter(outputter_ref_);
// Create trace marker while traces are disabled.
gl_fake_queries_.SetCurrentGLTime(start_timestamp);
@@ -485,9 +460,9 @@ class BaseGpuTracerTest : public BaseGpuTest {
ASSERT_TRUE(tracer.BeginDecoding());
// End decoding at time start+2.
- ExpectOutputterEndMocks(outputter_ref_.get(), source, category_name,
- trace_name, expect_start_time + 1,
- expect_start_time + 2, true, valid_timer);
+ ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
+ expect_start_time + 1, expect_start_time + 2, true,
+ valid_timer);
gl_fake_queries_.SetCurrentGLTime(
start_timestamp +
(2 * base::Time::kNanosecondsPerMicrosecond));
@@ -506,9 +481,9 @@ class BaseGpuTracerTest : public BaseGpuTest {
start_timestamp +
(4 * base::Time::kNanosecondsPerMicrosecond));
g_fakeCPUTime = expect_start_time + 4;
- ExpectOutputterEndMocks(outputter_ref_.get(), source, category_name,
- trace_name, expect_start_time + 3,
- expect_start_time + 4, true, valid_timer);
+ ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
+ expect_start_time + 3, expect_start_time + 4, true,
+ valid_timer);
ASSERT_TRUE(tracer.End(source));
// Increment time before we end decoding to test trace does not stop here.
@@ -538,13 +513,12 @@ class BaseGpuTracerTest : public BaseGpuTest {
(end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
GPUTracerTester tracer(&decoder);
tracer.SetTracingEnabled(true);
- tracer.SetOutputter(outputter_ref_);
-
gl_fake_queries_.SetCurrentGLTime(start_timestamp);
g_fakeCPUTime = expect_start_time;
@@ -552,8 +526,7 @@ class BaseGpuTracerTest : public BaseGpuTest {
ExpectTraceQueryMocks();
- ExpectOutputterBeginMocks(outputter_ref_.get(), source,
- category_name, trace_name);
+ ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
gl_fake_queries_.SetCurrentGLTime(end_timestamp);
@@ -570,18 +543,14 @@ class BaseGpuTracerTest : public BaseGpuTest {
gl_fake_queries_.SetDisjoint();
ASSERT_TRUE(disjoint_client->CheckAndResetTimerErrors());
- ExpectDisjointOutputMocks(outputter_ref_.get(),
- expect_start_time, expect_end_time);
+ ExpectDisjointOutputMocks(&outputter, expect_start_time, expect_end_time);
- ExpectOutputterEndMocks(outputter_ref_.get(), source,
- category_name, trace_name,
+ ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
expect_start_time, expect_end_time, true, false);
ASSERT_TRUE(tracer.End(source));
ASSERT_TRUE(tracer.EndDecoding());
tracer.ProcessTraces();
-
- outputter_ref_ = NULL;
}
void DoOutsideDisjointTest() {
@@ -601,11 +570,11 @@ class BaseGpuTracerTest : public BaseGpuTest {
(end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
FakeCommandBufferServiceBase command_buffer_service;
- MockGLES2Decoder decoder(&command_buffer_service);
+ MockOutputter outputter;
+ MockGLES2Decoder decoder(&command_buffer_service, &outputter);
EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
EXPECT_CALL(decoder, MakeCurrent()).WillRepeatedly(Return(true));
GPUTracerTester tracer(&decoder);
- tracer.SetOutputter(outputter_ref_);
// Start a trace before tracing is enabled.
tracer.SetTracingEnabled(false);
@@ -619,21 +588,19 @@ class BaseGpuTracerTest : public BaseGpuTest {
g_fakeCPUTime = expect_start_time;
// Disjoints before we start tracing anything should not do anything.
- ExpectNoDisjointOutputMocks(outputter_ref_.get());
+ ExpectNoDisjointOutputMocks(&outputter);
gl_fake_queries_.SetDisjoint();
ExpectTraceQueryMocks();
- ExpectOutputterBeginMocks(outputter_ref_.get(), source,
- category_name, trace_name);
+ ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
ASSERT_TRUE(tracer.BeginDecoding());
// Set times so each source has a different time.
gl_fake_queries_.SetCurrentGLTime(end_timestamp);
g_fakeCPUTime = expect_end_time;
- ExpectOutputterEndMocks(outputter_ref_.get(), source, category_name,
- trace_name, expect_start_time,
- expect_end_time, true, true);
+ ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
+ expect_start_time, expect_end_time, true, true);
ASSERT_TRUE(tracer.End(source));
ASSERT_TRUE(tracer.EndDecoding());
@@ -740,7 +707,7 @@ class GPUTracerTest : public GpuServiceTest {
void SetUp() override {
g_fakeCPUTime = 0;
GpuServiceTest::SetUpWithGLVersion("3.2", "");
- decoder_.reset(new MockGLES2Decoder(&command_buffer_service_));
+ decoder_.reset(new MockGLES2Decoder(&command_buffer_service_, &outputter_));
EXPECT_CALL(*decoder_, GetGLContext())
.Times(AtMost(1))
.WillRepeatedly(Return(GetGLContext()));
@@ -752,7 +719,9 @@ class GPUTracerTest : public GpuServiceTest {
decoder_ = nullptr;
GpuServiceTest::TearDown();
}
+
FakeCommandBufferServiceBase command_buffer_service_;
+ MockOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> decoder_;
std::unique_ptr<GPUTracerTester> tracer_tester_;
};
diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc b/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc
index d92d29f93ca..a515c57a191 100644
--- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc
+++ b/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc
@@ -7,8 +7,8 @@
#include <stddef.h>
#include <algorithm>
-#include <queue>
+#include "base/containers/queue.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/common/sync_token.h"
@@ -32,7 +32,7 @@ base::LazyInstance<base::Lock>::DestructorAtExit g_lock =
typedef std::map<SyncToken, std::unique_ptr<gl::GLFence>> SyncTokenToFenceMap;
base::LazyInstance<SyncTokenToFenceMap>::DestructorAtExit
g_sync_point_to_fence = LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<std::queue<SyncTokenToFenceMap::iterator>>::DestructorAtExit
+base::LazyInstance<base::queue<SyncTokenToFenceMap::iterator>>::DestructorAtExit
g_sync_points = LAZY_INSTANCE_INITIALIZER;
#endif
@@ -43,7 +43,7 @@ void CreateFenceLocked(const SyncToken& sync_token) {
gl::GetGLImplementation() == gl::kGLImplementationStubGL)
return;
- std::queue<SyncTokenToFenceMap::iterator>& sync_points = g_sync_points.Get();
+ base::queue<SyncTokenToFenceMap::iterator>& sync_points = g_sync_points.Get();
SyncTokenToFenceMap& sync_point_to_fence = g_sync_point_to_fence.Get();
if (sync_token.release_count()) {
while (!sync_points.empty() &&
diff --git a/chromium/gpu/command_buffer/service/query_manager.h b/chromium/gpu/command_buffer/service/query_manager.h
index e230b22df9e..ba0c34a68c9 100644
--- a/chromium/gpu/command_buffer/service/query_manager.h
+++ b/chromium/gpu/command_buffer/service/query_manager.h
@@ -7,11 +7,11 @@
#include <stdint.h>
-#include <deque>
#include <memory>
#include <vector>
#include "base/atomicops.h"
+#include "base/containers/circular_deque.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -298,18 +298,18 @@ class GPU_EXPORT QueryManager {
unsigned query_count_;
// Info for each query in the system.
- typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap;
+ using QueryMap = base::hash_map<GLuint, scoped_refptr<Query>>;
QueryMap queries_;
- typedef base::hash_set<GLuint> GeneratedQueryIds;
+ using GeneratedQueryIds = base::hash_set<GLuint>;
GeneratedQueryIds generated_query_ids_;
// A map of targets -> Query for current active queries.
- typedef std::map<GLenum, scoped_refptr<Query> > ActiveQueryMap;
+ using ActiveQueryMap = std::map<GLenum, scoped_refptr<Query>>;
ActiveQueryMap active_queries_;
// Queries waiting for completion.
- typedef std::deque<scoped_refptr<Query> > QueryQueue;
+ using QueryQueue = base::circular_deque<scoped_refptr<Query>>;
QueryQueue pending_queries_;
scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
diff --git a/chromium/gpu/command_buffer/service/query_manager_unittest.cc b/chromium/gpu/command_buffer/service/query_manager_unittest.cc
index 8c6f6ba801a..117528b4bb5 100644
--- a/chromium/gpu/command_buffer/service/query_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/query_manager_unittest.cc
@@ -14,6 +14,7 @@
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/query_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -69,7 +70,8 @@ class QueryManagerTest : public GpuServiceTest {
buffer = command_buffer_service_->CreateTransferBufferHelper(
kSharedBufferSize, &shared_memory2_id_);
memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize);
- decoder_.reset(new MockGLES2Decoder(command_buffer_service_.get()));
+ decoder_.reset(
+ new MockGLES2Decoder(command_buffer_service_.get(), &outputter_));
TestHelper::SetupFeatureInfoInitExpectations(
gl_.get(), extension_expectations);
EXPECT_CALL(*decoder_.get(), GetGLContext())
@@ -122,6 +124,7 @@ class QueryManagerTest : public GpuServiceTest {
manager_->EndQuery(query, submit_count);
}
+ TraceOutputter outputter_;
std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
std::unique_ptr<MockGLES2Decoder> decoder_;
std::unique_ptr<QueryManager> manager_;
diff --git a/chromium/gpu/command_buffer/service/sampler_manager.cc b/chromium/gpu/command_buffer/service/sampler_manager.cc
index 9b8ec3c4b65..1f9ca3e01b5 100644
--- a/chromium/gpu/command_buffer/service/sampler_manager.cc
+++ b/chromium/gpu/command_buffer/service/sampler_manager.cc
@@ -112,7 +112,7 @@ GLenum Sampler::SetParameterf(
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_COMPARE_FUNC:
case GL_TEXTURE_COMPARE_MODE: {
- GLint iparam = static_cast<GLint>(param);
+ GLint iparam = static_cast<GLint>(std::round(param));
return SetParameteri(feature_info, pname, iparam);
}
case GL_TEXTURE_MIN_LOD:
diff --git a/chromium/gpu/command_buffer/service/scheduler.cc b/chromium/gpu/command_buffer/service/scheduler.cc
index f240ab9a54e..91f813cb6bf 100644
--- a/chromium/gpu/command_buffer/service/scheduler.cc
+++ b/chromium/gpu/command_buffer/service/scheduler.cc
@@ -7,6 +7,8 @@
#include <algorithm>
#include "base/callback.h"
+#include "base/containers/circular_deque.h"
+#include "base/containers/flat_set.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
@@ -83,6 +85,10 @@ class Scheduler::Sequence {
// Remove a release sync token fence.
void RemoveReleaseFence(const SyncToken& sync_token, uint32_t order_num);
+ void AddClientWait(CommandBufferId command_buffer_id);
+
+ void RemoveClientWait(CommandBufferId command_buffer_id);
+
private:
enum RunningState { IDLE, SCHEDULED, RUNNING };
@@ -122,7 +128,7 @@ class Scheduler::Sequence {
// Deque of tasks. Tasks are inserted at the back with increasing order number
// generated from SyncPointOrderData. If a running task needs to be continued,
// it is inserted at the front with the same order number.
- std::deque<Task> tasks_;
+ base::circular_deque<Task> tasks_;
// List of fences that this sequence is waiting on. Fences are inserted in
// increasing order number but may be removed out of order. Tasks are blocked
@@ -134,6 +140,8 @@ class Scheduler::Sequence {
// non-empty, the priority of the sequence is raised.
std::vector<Fence> release_fences_;
+ base::flat_set<CommandBufferId> client_waits_;
+
DISALLOW_COPY_AND_ASSIGN(Sequence);
};
@@ -174,9 +182,10 @@ Scheduler::Sequence::~Sequence() {
}
SchedulingPriority Scheduler::Sequence::GetSchedulingPriority() const {
- if (!release_fences_.empty())
- return std::min(priority_, SchedulingPriority::kHigh);
- return priority_;
+ SchedulingPriority priority = priority_;
+ if (!release_fences_.empty() || !client_waits_.empty())
+ priority = std::min(priority, SchedulingPriority::kHigh);
+ return priority;
}
bool Scheduler::Sequence::NeedsRescheduling() const {
@@ -201,6 +210,13 @@ void Scheduler::Sequence::SetEnabled(bool enabled) {
return;
DCHECK_EQ(running_state_, enabled ? IDLE : RUNNING);
enabled_ = enabled;
+ if (enabled) {
+ TRACE_EVENT_ASYNC_BEGIN1("gpu", "SequenceEnabled", this, "sequence_id",
+ sequence_id_.GetUnsafeValue());
+ } else {
+ TRACE_EVENT_ASYNC_END1("gpu", "SequenceEnabled", this, "sequence_id",
+ sequence_id_.GetUnsafeValue());
+ }
}
Scheduler::SchedulingState Scheduler::Sequence::SetScheduled() {
@@ -273,6 +289,14 @@ void Scheduler::Sequence::RemoveReleaseFence(const SyncToken& sync_token,
base::Erase(release_fences_, Fence{sync_token, order_num});
}
+void Scheduler::Sequence::AddClientWait(CommandBufferId command_buffer_id) {
+ client_waits_.insert(command_buffer_id);
+}
+
+void Scheduler::Sequence::RemoveClientWait(CommandBufferId command_buffer_id) {
+ client_waits_.erase(command_buffer_id);
+}
+
Scheduler::Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
SyncPointManager* sync_point_manager)
: task_runner_(std::move(task_runner)),
@@ -334,6 +358,26 @@ void Scheduler::DisableSequence(SequenceId sequence_id) {
sequence->SetEnabled(false);
}
+void Scheduler::RaisePriorityForClientWait(SequenceId sequence_id,
+ CommandBufferId command_buffer_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ base::AutoLock auto_lock(lock_);
+ Sequence* sequence = GetSequence(sequence_id);
+ DCHECK(sequence);
+ sequence->AddClientWait(command_buffer_id);
+ TryScheduleSequence(sequence);
+}
+
+void Scheduler::ResetPriorityForClientWait(SequenceId sequence_id,
+ CommandBufferId command_buffer_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ base::AutoLock auto_lock(lock_);
+ Sequence* sequence = GetSequence(sequence_id);
+ DCHECK(sequence);
+ sequence->RemoveClientWait(command_buffer_id);
+ TryScheduleSequence(sequence);
+}
+
void Scheduler::ScheduleTask(Task task) {
base::AutoLock auto_lock(lock_);
ScheduleTaskHelper(std::move(task));
diff --git a/chromium/gpu/command_buffer/service/scheduler.h b/chromium/gpu/command_buffer/service/scheduler.h
index 850107ac883..179df74ec2e 100644
--- a/chromium/gpu/command_buffer/service/scheduler.h
+++ b/chromium/gpu/command_buffer/service/scheduler.h
@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
+#include "gpu/command_buffer/common/command_buffer_id.h"
#include "gpu/command_buffer/common/scheduling_priority.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/command_buffer/service/sequence_id.h"
@@ -63,6 +64,15 @@ class GPU_EXPORT Scheduler {
// Disables the sequence.
void DisableSequence(SequenceId sequence_id);
+ // Raise priority of sequence for client wait (WaitForGetOffset/TokenInRange)
+ // on given command buffer.
+ void RaisePriorityForClientWait(SequenceId sequence_id,
+ CommandBufferId command_buffer_id);
+
+ // Reset priority of sequence if it was increased for a client wait.
+ void ResetPriorityForClientWait(SequenceId sequence_id,
+ CommandBufferId command_buffer_id);
+
// Schedules task (closure) to run on the sequence. The task is blocked until
// the sync token fences are released or determined to be invalid. Tasks are
// run in the order in which they are submitted.
@@ -99,7 +109,7 @@ class GPU_EXPORT Scheduler {
const;
SequenceId sequence_id;
- SchedulingPriority priority = SchedulingPriority::kLowest;
+ SchedulingPriority priority = SchedulingPriority::kLow;
uint32_t order_num = 0;
};
diff --git a/chromium/gpu/command_buffer/service/scheduler_unittest.cc b/chromium/gpu/command_buffer/service/scheduler_unittest.cc
index 1037ab9fdce..9c0be7e2ac7 100644
--- a/chromium/gpu/command_buffer/service/scheduler_unittest.cc
+++ b/chromium/gpu/command_buffer/service/scheduler_unittest.cc
@@ -99,7 +99,7 @@ TEST_F(SchedulerTest, ContinuedTasksRunFirst) {
TEST_F(SchedulerTest, SequencesRunInPriorityOrder) {
SequenceId sequence_id1 =
- scheduler()->CreateSequence(SchedulingPriority::kLowest);
+ scheduler()->CreateSequence(SchedulingPriority::kLow);
bool ran1 = false;
scheduler()->ScheduleTask(Scheduler::Task(sequence_id1,
GetClosure([&] { ran1 = true; }),
@@ -113,7 +113,7 @@ TEST_F(SchedulerTest, SequencesRunInPriorityOrder) {
std::vector<SyncToken>()));
SequenceId sequence_id3 =
- scheduler()->CreateSequence(SchedulingPriority::kHighest);
+ scheduler()->CreateSequence(SchedulingPriority::kHigh);
bool ran3 = false;
scheduler()->ScheduleTask(Scheduler::Task(sequence_id3,
GetClosure([&] { ran3 = true; }),
@@ -173,7 +173,7 @@ TEST_F(SchedulerTest, SequencesOfSamePriorityRunInOrder) {
TEST_F(SchedulerTest, SequenceWaitsForFence) {
SequenceId sequence_id1 =
- scheduler()->CreateSequence(SchedulingPriority::kHighest);
+ scheduler()->CreateSequence(SchedulingPriority::kHigh);
SequenceId sequence_id2 =
scheduler()->CreateSequence(SchedulingPriority::kNormal);
@@ -261,7 +261,7 @@ TEST_F(SchedulerTest, ReleaseSequenceIsPrioritized) {
std::vector<SyncToken>()));
SequenceId sequence_id2 =
- scheduler()->CreateSequence(SchedulingPriority::kLowest);
+ scheduler()->CreateSequence(SchedulingPriority::kLow);
CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1);
scoped_refptr<SyncPointClientState> release_state =
@@ -280,7 +280,7 @@ TEST_F(SchedulerTest, ReleaseSequenceIsPrioritized) {
bool ran3 = false;
SyncToken sync_token(namespace_id, 0, command_buffer_id, release);
SequenceId sequence_id3 =
- scheduler()->CreateSequence(SchedulingPriority::kHighest);
+ scheduler()->CreateSequence(SchedulingPriority::kHigh);
scheduler()->ScheduleTask(Scheduler::Task(
sequence_id3, GetClosure([&] { ran3 = true; }), {sync_token}));
@@ -302,7 +302,7 @@ TEST_F(SchedulerTest, ReleaseSequenceIsPrioritized) {
TEST_F(SchedulerTest, ReleaseSequenceShouldYield) {
SequenceId sequence_id1 =
- scheduler()->CreateSequence(SchedulingPriority::kLowest);
+ scheduler()->CreateSequence(SchedulingPriority::kLow);
CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1);
scoped_refptr<SyncPointClientState> release_state =
@@ -323,7 +323,7 @@ TEST_F(SchedulerTest, ReleaseSequenceShouldYield) {
bool ran2 = false;
SyncToken sync_token(namespace_id, 0, command_buffer_id, release);
SequenceId sequence_id2 =
- scheduler()->CreateSequence(SchedulingPriority::kHighest);
+ scheduler()->CreateSequence(SchedulingPriority::kHigh);
scheduler()->ScheduleTask(Scheduler::Task(
sequence_id2, GetClosure([&] { ran2 = true; }), {sync_token}));
@@ -418,5 +418,69 @@ TEST_F(SchedulerTest, WaitOnSelfShouldNotBlockSequence) {
release_state->Destroy();
}
+TEST_F(SchedulerTest, ClientWaitIsPrioritized) {
+ SequenceId sequence_id1 =
+ scheduler()->CreateSequence(SchedulingPriority::kNormal);
+
+ bool ran1 = false;
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id1,
+ GetClosure([&] { ran1 = true; }),
+ std::vector<SyncToken>()));
+
+ SequenceId sequence_id2 =
+ scheduler()->CreateSequence(SchedulingPriority::kLow);
+ CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1);
+ bool ran2 = false;
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id2,
+ GetClosure([&] { ran2 = true; }),
+ std::vector<SyncToken>()));
+
+ bool ran3 = false;
+ SequenceId sequence_id3 =
+ scheduler()->CreateSequence(SchedulingPriority::kHigh);
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id3,
+ GetClosure([&] { ran3 = true; }),
+ std::vector<SyncToken>()));
+
+ scheduler()->RaisePriorityForClientWait(sequence_id2, command_buffer_id);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_FALSE(ran1);
+ EXPECT_TRUE(ran2);
+ EXPECT_FALSE(ran3);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_FALSE(ran1);
+ EXPECT_TRUE(ran3);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_TRUE(ran1);
+
+ ran1 = ran2 = ran3 = false;
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id1,
+ GetClosure([&] { ran1 = true; }),
+ std::vector<SyncToken>()));
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id2,
+ GetClosure([&] { ran2 = true; }),
+ std::vector<SyncToken>()));
+ scheduler()->ScheduleTask(Scheduler::Task(sequence_id3,
+ GetClosure([&] { ran3 = true; }),
+ std::vector<SyncToken>()));
+
+ scheduler()->ResetPriorityForClientWait(sequence_id2, command_buffer_id);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_FALSE(ran1);
+ EXPECT_FALSE(ran2);
+ EXPECT_TRUE(ran3);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_TRUE(ran1);
+ EXPECT_FALSE(ran2);
+
+ task_runner()->RunPendingTasks();
+ EXPECT_TRUE(ran2);
+}
+
} // namespace
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc
index 32131398662..fa759064c4d 100644
--- a/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/memory_tracking.h"
@@ -67,7 +68,7 @@ class ServiceDiscardableManagerTest : public GpuServiceTest {
protected:
void SetUp() override {
GpuServiceTest::SetUp();
- decoder_.reset(new MockGLES2Decoder(&command_buffer_service_));
+ decoder_.reset(new MockGLES2Decoder(&command_buffer_service_, &outputter_));
feature_info_ = new FeatureInfo();
context_group_ = scoped_refptr<ContextGroup>(new ContextGroup(
gpu_preferences_, false, &mailbox_manager_, nullptr, nullptr, nullptr,
@@ -114,6 +115,7 @@ class ServiceDiscardableManagerTest : public GpuServiceTest {
}
MailboxManagerImpl mailbox_manager_;
+ TraceOutputter outputter_;
ImageManager image_manager_;
ServiceDiscardableManager discardable_manager_;
GpuPreferences gpu_preferences_;
diff --git a/chromium/gpu/command_buffer/service/service_utils.cc b/chromium/gpu/command_buffer/service/service_utils.cc
index e8f2b6195ec..7e86f9f3c16 100644
--- a/chromium/gpu/command_buffer/service/service_utils.cc
+++ b/chromium/gpu/command_buffer/service/service_utils.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "ui/gl/gl_switches.h"
#if defined(USE_EGL)
@@ -31,6 +32,8 @@ gl::GLContextAttribs GenerateGLContextAttribs(
// decoder
attribs.global_texture_share_group = true;
+ attribs.robust_resource_initialization = true;
+
// Request a specific context version instead of always 3.0
if (IsWebGL2OrES3ContextType(attribs_helper.context_type)) {
attribs.client_major_es_version = 3;
@@ -55,6 +58,10 @@ gl::GLContextAttribs GenerateGLContextAttribs(
return attribs;
}
+bool UsePassthroughCommandDecoder(const base::CommandLine* command_line) {
+ return command_line->HasSwitch(switches::kUsePassthroughCmdDecoder);
+}
+
bool PassthroughCommandDecoderSupported() {
#if defined(USE_EGL)
// Using the passthrough command buffer requires that specific ANGLE
diff --git a/chromium/gpu/command_buffer/service/service_utils.h b/chromium/gpu/command_buffer/service/service_utils.h
index 5eae2d3b8b1..5817aced601 100644
--- a/chromium/gpu/command_buffer/service/service_utils.h
+++ b/chromium/gpu/command_buffer/service/service_utils.h
@@ -5,6 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_SERVICE_UTILS_H_
#define GPU_COMMAND_BUFFER_SERVICE_SERVICE_UTILS_H_
+#include "base/command_line.h"
#include "gpu/gpu_export.h"
#include "ui/gl/gl_context.h"
@@ -18,6 +19,10 @@ GPU_EXPORT gl::GLContextAttribs GenerateGLContextAttribs(
const ContextCreationAttribHelper& attribs_helper,
const ContextGroup* context_group);
+// Returns true if the passthrough command decoder has been requested
+GPU_EXPORT bool UsePassthroughCommandDecoder(
+ const base::CommandLine* command_line);
+
// Returns true if the driver supports creating passthrough command decoders
GPU_EXPORT bool PassthroughCommandDecoderSupported();
diff --git a/chromium/gpu/command_buffer/service/shader_translator.cc b/chromium/gpu/command_buffer/service/shader_translator.cc
index a22b67970d9..dda5586f334 100644
--- a/chromium/gpu/command_buffer/service/shader_translator.cc
+++ b/chromium/gpu/command_buffer/service/shader_translator.cc
@@ -169,10 +169,10 @@ bool ShaderTranslator::Init(GLenum shader_type,
shader_output_language, resources);
}
- compile_options_ =
- SH_OBJECT_CODE | SH_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS |
- SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH |
- SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
+ compile_options_ = SH_OBJECT_CODE | SH_VARIABLES |
+ SH_ENFORCE_PACKING_RESTRICTIONS |
+ SH_LIMIT_EXPRESSION_COMPLEXITY |
+ SH_LIMIT_CALL_STACK_DEPTH | SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
if (gl_shader_interm_output)
compile_options_ |= SH_INTERMEDIATE_TREE;
compile_options_ |= driver_bug_workarounds;
diff --git a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc
index d548498259d..8962c633304 100644
--- a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -245,7 +245,8 @@ TEST_F(ShaderTranslatorTest, GetAttributes) {
// There should be one attribute with following characteristics:
// name:vPosition type:GL_FLOAT_VEC4 size:0.
EXPECT_EQ(1u, attrib_map.size());
- AttributeMap::const_iterator iter = attrib_map.find("vPosition");
+ // The shader translator adds a "_u" prefix to user-defined names.
+ AttributeMap::const_iterator iter = attrib_map.find("_uvPosition");
EXPECT_TRUE(iter != attrib_map.end());
EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), iter->second.type);
EXPECT_EQ(0u, iter->second.arraySize);
@@ -289,20 +290,21 @@ TEST_F(ShaderTranslatorTest, GetUniforms) {
// 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
// However, there will be only one entry "bar" in the map.
EXPECT_EQ(1u, uniform_map.size());
- UniformMap::const_iterator iter = uniform_map.find("bar");
+ // The shader translator adds a "_u" prefix to user-defined names.
+ UniformMap::const_iterator iter = uniform_map.find("_ubar");
EXPECT_TRUE(iter != uniform_map.end());
// First uniform.
const sh::ShaderVariable* info;
std::string original_name;
- EXPECT_TRUE(iter->second.findInfoByMappedName(
- "bar[0].foo.color[0]", &info, &original_name));
+ EXPECT_TRUE(iter->second.findInfoByMappedName("_ubar[0]._ufoo._ucolor[0]",
+ &info, &original_name));
EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
EXPECT_EQ(1u, info->arraySize);
EXPECT_STREQ("color", info->name.c_str());
EXPECT_STREQ("bar[0].foo.color[0]", original_name.c_str());
// Second uniform.
- EXPECT_TRUE(iter->second.findInfoByMappedName(
- "bar[1].foo.color[0]", &info, &original_name));
+ EXPECT_TRUE(iter->second.findInfoByMappedName("_ubar[1]._ufoo._ucolor[0]",
+ &info, &original_name));
EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
EXPECT_EQ(1u, info->arraySize);
EXPECT_STREQ("color", info->name.c_str());
diff --git a/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc b/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc
index 48600b3ca65..9a1e1e0f4ec 100644
--- a/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc
@@ -5,9 +5,9 @@
#include <stdint.h>
#include <memory>
-#include <queue>
#include "base/bind.h"
+#include "base/containers/queue.h"
#include "base/memory/ptr_util.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,7 +29,7 @@ class SyncPointManagerTest : public testing::Test {
struct SyncPointStream {
scoped_refptr<SyncPointOrderData> order_data;
scoped_refptr<SyncPointClientState> client_state;
- std::queue<uint32_t> order_numbers;
+ base::queue<uint32_t> order_numbers;
SyncPointStream(SyncPointManager* sync_point_manager,
CommandBufferNamespace namespace_id,
diff --git a/chromium/gpu/command_buffer/service/test_helper.cc b/chromium/gpu/command_buffer/service/test_helper.cc
index 27686d752e8..b81ec7496cf 100644
--- a/chromium/gpu/command_buffer/service/test_helper.cc
+++ b/chromium/gpu/command_buffer/service/test_helper.cc
@@ -624,26 +624,9 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
}
if (!enable_es3 &&
!gl::HasExtension(extension_set, "GL_EXT_color_buffer_half_float") &&
- (gl_info.is_es || gl_info.IsAtLeastGL(3, 0))) {
- EXPECT_CALL(
- *gl,
- TexImage2D(GL_TEXTURE_2D, 0, GL_R16F, width, width, 0, GL_RED, _, _))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(
- *gl,
- TexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, width, width, 0, GL_RG, _, _))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl,
- TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, width, 0,
- GL_RGBA, _, _))
+ (gl_info.IsAtLeastGLES(3, 0) || gl_info.IsAtLeastGL(3, 0))) {
+ EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, width, 0,
+ GL_RGBA, GL_HALF_FLOAT, nullptr))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
@@ -1263,4 +1246,3 @@ sh::OutputVariable TestHelper::ConstructOutputVariable(
} // namespace gles2
} // namespace gpu
-
diff --git a/chromium/gpu/command_buffer/service/texture_manager.cc b/chromium/gpu/command_buffer/service/texture_manager.cc
index acd6afabe7d..9dafeeaed65 100644
--- a/chromium/gpu/command_buffer/service/texture_manager.cc
+++ b/chromium/gpu/command_buffer/service/texture_manager.cc
@@ -350,6 +350,11 @@ bool SizedFormatAvailable(const FeatureInfo* feature_info,
if (immutable)
return true;
+ if (feature_info->feature_flags().ext_texture_norm16 &&
+ internal_format == GL_R16_EXT) {
+ return true;
+ }
+
if ((feature_info->feature_flags().chromium_image_ycbcr_420v &&
internal_format == GL_RGB_YCBCR_420V_CHROMIUM) ||
(feature_info->feature_flags().chromium_image_ycbcr_422 &&
diff --git a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc
index 92a2c7675c2..5847b1f76fb 100644
--- a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -19,6 +19,7 @@
#include "gpu/command_buffer/service/gl_stream_texture_image.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/mocks.h"
@@ -87,7 +88,7 @@ class TextureManagerTest : public GpuServiceTest {
TestHelper::SetupTextureManagerInitExpectations(
gl_.get(), false, false, false, {}, kUseDefaultTextures);
manager_->Initialize();
- error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
+ error_state_.reset(new ::testing::StrictMock<MockErrorState>());
}
void TearDown() override {
@@ -677,9 +678,9 @@ class TextureTestBase : public GpuServiceTest {
kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize,
kMaxArrayTextureLayers, kUseDefaultTextures, nullptr,
&discardable_manager_));
- decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>(
- &command_buffer_service_));
- error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
+ decoder_.reset(new ::testing::StrictMock<MockGLES2Decoder>(
+ &command_buffer_service_, &outputter_));
+ error_state_.reset(new ::testing::StrictMock<MockErrorState>());
manager_->CreateTexture(kClient1Id, kService1Id);
texture_ref_ = manager_->GetTexture(kClient1Id);
ASSERT_TRUE(texture_ref_.get() != NULL);
@@ -711,6 +712,7 @@ class TextureTestBase : public GpuServiceTest {
}
FakeCommandBufferServiceBase command_buffer_service_;
+ TraceOutputter outputter_;
std::unique_ptr<MockGLES2Decoder> decoder_;
std::unique_ptr<MockErrorState> error_state_;
scoped_refptr<FeatureInfo> feature_info_;