diff options
author | Andras Becsi <andras.becsi@digia.com> | 2013-12-11 21:33:03 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-12-13 12:34:07 +0100 |
commit | f2a33ff9cbc6d19943f1c7fbddd1f23d23975577 (patch) | |
tree | 0586a32aa390ade8557dfd6b4897f43a07449578 /chromium/cc/debug | |
parent | 5362912cdb5eea702b68ebe23702468d17c3017a (diff) | |
download | qtwebengine-chromium-f2a33ff9cbc6d19943f1c7fbddd1f23d23975577.tar.gz |
Update Chromium to branch 1650 (31.0.1650.63)
Change-Id: I57d8c832eaec1eb2364e0a8e7352a6dd354db99f
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'chromium/cc/debug')
-rw-r--r-- | chromium/cc/debug/devtools_instrumentation.h | 17 | ||||
-rw-r--r-- | chromium/cc/debug/fake_web_graphics_context_3d.h | 3 | ||||
-rw-r--r-- | chromium/cc/debug/frame_rate_counter.cc | 24 | ||||
-rw-r--r-- | chromium/cc/debug/frame_rate_counter.h | 2 | ||||
-rw-r--r-- | chromium/cc/debug/overdraw_metrics.cc | 14 | ||||
-rw-r--r-- | chromium/cc/debug/rendering_stats.cc | 233 | ||||
-rw-r--r-- | chromium/cc/debug/rendering_stats.h | 106 | ||||
-rw-r--r-- | chromium/cc/debug/rendering_stats_instrumentation.cc | 85 | ||||
-rw-r--r-- | chromium/cc/debug/rendering_stats_instrumentation.h | 35 | ||||
-rw-r--r-- | chromium/cc/debug/test_context_provider.cc | 240 | ||||
-rw-r--r-- | chromium/cc/debug/test_context_provider.h | 90 | ||||
-rw-r--r-- | chromium/cc/debug/test_web_graphics_context_3d.cc | 632 | ||||
-rw-r--r-- | chromium/cc/debug/test_web_graphics_context_3d.h | 292 | ||||
-rw-r--r-- | chromium/cc/debug/traced_picture.cc | 30 | ||||
-rw-r--r-- | chromium/cc/debug/traced_picture.h | 7 |
15 files changed, 1648 insertions, 162 deletions
diff --git a/chromium/cc/debug/devtools_instrumentation.h b/chromium/cc/debug/devtools_instrumentation.h index 7a77d404454..eea9e62f02a 100644 --- a/chromium/cc/debug/devtools_instrumentation.h +++ b/chromium/cc/debug/devtools_instrumentation.h @@ -14,11 +14,13 @@ namespace internal { const char kCategory[] = "cc,devtools"; const char kLayerId[] = "layerId"; const char kLayerTreeId[] = "layerTreeId"; +const char kPixelRefId[] = "pixelRefId"; + +const char kImageDecodeTask[] = "ImageDecodeTask"; } const char kPaintLayer[] = "PaintLayer"; const char kRasterTask[] = "RasterTask"; -const char kImageDecodeTask[] = "ImageDecodeTask"; const char kPaintSetup[] = "PaintSetup"; const char kUpdateLayer[] = "UpdateLayer"; @@ -38,6 +40,19 @@ class ScopedLayerTask { DISALLOW_COPY_AND_ASSIGN(ScopedLayerTask); }; +class ScopedImageDecodeTask { + public: + explicit ScopedImageDecodeTask(void* pixelRef) { + TRACE_EVENT_BEGIN1(internal::kCategory, internal::kImageDecodeTask, + internal::kPixelRefId, reinterpret_cast<uint64>(pixelRef)); + } + ~ScopedImageDecodeTask() { + TRACE_EVENT_END0(internal::kCategory, internal::kImageDecodeTask); + } + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImageDecodeTask); +}; + class ScopedLayerTreeTask { public: ScopedLayerTreeTask(const char* event_name, diff --git a/chromium/cc/debug/fake_web_graphics_context_3d.h b/chromium/cc/debug/fake_web_graphics_context_3d.h index 3c8a6f53b76..04c983de006 100644 --- a/chromium/cc/debug/fake_web_graphics_context_3d.h +++ b/chromium/cc/debug/fake_web_graphics_context_3d.h @@ -67,9 +67,6 @@ class CC_EXPORT FakeWebGraphicsContext3D WebKit::WGC3Dsizei num_attachments, const WebKit::WGC3Denum* attachments) {} - virtual void setMemoryAllocationChangedCallbackCHROMIUM( - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {} - virtual WebKit::WebString getRequestableExtensionsCHROMIUM(); virtual void requestExtensionCHROMIUM(const char*) {} diff --git a/chromium/cc/debug/frame_rate_counter.cc b/chromium/cc/debug/frame_rate_counter.cc index 8a829ff711a..2f3b291fea9 100644 --- a/chromium/cc/debug/frame_rate_counter.cc +++ b/chromium/cc/debug/frame_rate_counter.cc @@ -44,7 +44,7 @@ base::TimeDelta FrameRateCounter::RecentFrameInterval(size_t n) const { FrameRateCounter::FrameRateCounter(bool has_impl_thread) : has_impl_thread_(has_impl_thread), dropped_frame_count_(0) {} -void FrameRateCounter::SaveTimeStamp(base::TimeTicks timestamp) { +void FrameRateCounter::SaveTimeStamp(base::TimeTicks timestamp, bool software) { ring_buffer_.SaveToBuffer(timestamp); // Check if frame interval can be computed. @@ -55,16 +55,26 @@ void FrameRateCounter::SaveTimeStamp(base::TimeTicks timestamp) { RecentFrameInterval(ring_buffer_.BufferSize() - 1); if (has_impl_thread_ && ring_buffer_.CurrentIndex() > 0) { - UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", - frame_interval_seconds.InMilliseconds(), - 1, - 120, - 60); + if (software) { + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Renderer4.SoftwareCompositorThreadImplDrawDelay", + frame_interval_seconds.InMilliseconds(), + 1, + 120, + 60); + } else { + UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", + frame_interval_seconds.InMilliseconds(), + 1, + 120, + 60); + } } if (!IsBadFrameInterval(frame_interval_seconds) && frame_interval_seconds.InSecondsF() > kDroppedFrameTime) - ++dropped_frame_count_; + dropped_frame_count_ += + frame_interval_seconds.InSecondsF() / kDroppedFrameTime; } bool FrameRateCounter::IsBadFrameInterval( diff --git a/chromium/cc/debug/frame_rate_counter.h b/chromium/cc/debug/frame_rate_counter.h index 32b4c2c24f1..0b69b29aea5 100644 --- a/chromium/cc/debug/frame_rate_counter.h +++ b/chromium/cc/debug/frame_rate_counter.h @@ -22,7 +22,7 @@ class FrameRateCounter { int dropped_frame_count() const { return dropped_frame_count_; } size_t time_stamp_history_size() const { return ring_buffer_.BufferSize(); } - void SaveTimeStamp(base::TimeTicks timestamp); + void SaveTimeStamp(base::TimeTicks timestamp, bool software); // n = 0 returns the oldest frame interval retained in the history, while n = // time_stamp_history_size() - 1 returns the most recent frame interval. diff --git a/chromium/cc/debug/overdraw_metrics.cc b/chromium/cc/debug/overdraw_metrics.cc index 5b19370fe2c..a14284d800d 100644 --- a/chromium/cc/debug/overdraw_metrics.cc +++ b/chromium/cc/debug/overdraw_metrics.cc @@ -147,11 +147,11 @@ void OverdrawMetrics::RecordMetrics( } } -static gfx::Size DeviceViewportSize(const LayerTreeHost* host) { +static gfx::Size DrawViewportSize(const LayerTreeHost* host) { return host->device_viewport_size(); } -static gfx::Size DeviceViewportSize(const LayerTreeHostImpl* host_impl) { - return host_impl->device_viewport_size(); +static gfx::Size DrawViewportSize(const LayerTreeHostImpl* host_impl) { + return host_impl->DrawViewportSize(); } template <typename LayerTreeHostType> @@ -160,13 +160,13 @@ void OverdrawMetrics::RecordMetricsInternal( const LayerTreeHostType* layer_tree_host) const { // This gives approximately 10x the percentage of pixels to fill the viewport // once. - float normalization = 1000.f / (DeviceViewportSize(layer_tree_host).width() * - DeviceViewportSize(layer_tree_host).height()); + float normalization = 1000.f / (DrawViewportSize(layer_tree_host).width() * + DrawViewportSize(layer_tree_host).height()); // This gives approximately 100x the percentage of tiles to fill the viewport // once, if all tiles were 256x256. float tile_normalization = - 10000.f / (DeviceViewportSize(layer_tree_host).width() / 256.f * - DeviceViewportSize(layer_tree_host).height() / 256.f); + 10000.f / (DrawViewportSize(layer_tree_host).width() / 256.f * + DrawViewportSize(layer_tree_host).height() / 256.f); // This gives approximately 10x the percentage of bytes to fill the viewport // once, assuming 4 bytes per pixel. float byte_normalization = normalization / 4; diff --git a/chromium/cc/debug/rendering_stats.cc b/chromium/cc/debug/rendering_stats.cc index 12c54530c71..64cf69e0fe3 100644 --- a/chromium/cc/debug/rendering_stats.cc +++ b/chromium/cc/debug/rendering_stats.cc @@ -2,98 +2,195 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/values.h" #include "cc/debug/rendering_stats.h" namespace cc { -RenderingStats::RenderingStats() - : animation_frame_count(0), - screen_frame_count(0), +MainThreadRenderingStats::MainThreadRenderingStats() + : animation_frame_count(0), + screen_frame_count(0), + commit_count(0), + painted_pixel_count(0), + recorded_pixel_count(0), + image_gathering_count(0) {} + +ImplThreadRenderingStats::ImplThreadRenderingStats() + : screen_frame_count(0), dropped_frame_count(0), - total_commit_count(0), - total_pixels_painted(0), - total_pixels_recorded(0), - total_pixels_rasterized(0), - num_impl_thread_scrolls(0), - num_main_thread_scrolls(0), - num_layers_drawn(0), - num_missing_tiles(0), - total_deferred_image_decode_count(0), - total_deferred_image_cache_hit_count(0), - total_image_gathering_count(0), - total_tiles_analyzed(0), - solid_color_tiles_analyzed(0) {} + rasterized_pixel_count(0), + impl_thread_scroll_count(0), + main_thread_scroll_count(0), + drawn_layer_count(0), + missing_tile_count(0), + deferred_image_decode_count(0), + deferred_image_cache_hit_count(0), + tile_analysis_count(0), + solid_color_tile_analysis_count(0) {} void RenderingStats::EnumerateFields(Enumerator* enumerator) const { - enumerator->AddInt64("numAnimationFrames", animation_frame_count); - enumerator->AddInt64("numFramesSentToScreen", screen_frame_count); - enumerator->AddInt64("droppedFrameCount", dropped_frame_count); + enumerator->AddInt64("numAnimationFrames", + main_stats.animation_frame_count); + enumerator->AddInt64("numFramesSentToScreen", main_stats.screen_frame_count + + impl_stats.screen_frame_count); enumerator->AddDouble("totalPaintTimeInSeconds", - total_paint_time.InSecondsF()); + main_stats.paint_time.InSecondsF()); enumerator->AddDouble("totalRecordTimeInSeconds", - total_record_time.InSecondsF()); + main_stats.record_time.InSecondsF()); + enumerator->AddDouble("totalCommitTimeInSeconds", + main_stats.commit_time.InSecondsF()); + enumerator->AddInt64("totalCommitCount", main_stats.commit_count); + enumerator->AddInt64("totalPixelsPainted", main_stats.painted_pixel_count); + enumerator->AddInt64("totalPixelsRecorded", main_stats.recorded_pixel_count); + enumerator->AddInt64("totalImageGatheringCount", + main_stats.image_gathering_count); + enumerator->AddDouble("totalImageGatheringTimeInSeconds", + main_stats.image_gathering_time.InSecondsF()); + enumerator->AddInt64("droppedFrameCount", impl_stats.dropped_frame_count); enumerator->AddDouble("totalRasterizeTimeInSeconds", - total_rasterize_time.InSecondsF()); + impl_stats.rasterize_time.InSecondsF()); enumerator->AddDouble( "totalRasterizeTimeForNowBinsOnPendingTree", - total_rasterize_time_for_now_bins_on_pending_tree.InSecondsF()); - enumerator->AddDouble("totalCommitTimeInSeconds", - total_commit_time.InSecondsF()); + impl_stats.rasterize_time_for_now_bins_on_pending_tree.InSecondsF()); enumerator->AddDouble("bestRasterizeTimeInSeconds", - best_rasterize_time.InSecondsF()); - enumerator->AddInt64("totalCommitCount", total_commit_count); - enumerator->AddInt64("totalPixelsPainted", total_pixels_painted); - enumerator->AddInt64("totalPixelsRecorded", total_pixels_recorded); - enumerator->AddInt64("totalPixelsRasterized", total_pixels_rasterized); - enumerator->AddInt64("numImplThreadScrolls", num_impl_thread_scrolls); - enumerator->AddInt64("numMainThreadScrolls", num_main_thread_scrolls); - enumerator->AddInt64("numLayersDrawn", num_layers_drawn); - enumerator->AddInt64("numMissingTiles", num_missing_tiles); + impl_stats.best_rasterize_time.InSecondsF()); + enumerator->AddInt64("totalPixelsRasterized", + impl_stats.rasterized_pixel_count); + enumerator->AddInt64("numImplThreadScrolls", + impl_stats.impl_thread_scroll_count); + enumerator->AddInt64("numMainThreadScrolls", + impl_stats.main_thread_scroll_count); + enumerator->AddInt64("numLayersDrawn", impl_stats.drawn_layer_count); + enumerator->AddInt64("numMissingTiles", impl_stats.missing_tile_count); enumerator->AddInt64("totalDeferredImageDecodeCount", - total_deferred_image_decode_count); - enumerator->AddInt64("totalTilesAnalyzed", total_tiles_analyzed); + impl_stats.deferred_image_decode_count); + enumerator->AddInt64("totalTilesAnalyzed", impl_stats.tile_analysis_count); enumerator->AddInt64("solidColorTilesAnalyzed", - solid_color_tiles_analyzed); + impl_stats.solid_color_tile_analysis_count); enumerator->AddInt64("totalDeferredImageCacheHitCount", - total_deferred_image_cache_hit_count); - enumerator->AddInt64("totalImageGatheringCount", - total_image_gathering_count); + impl_stats.deferred_image_cache_hit_count); enumerator->AddDouble("totalDeferredImageDecodeTimeInSeconds", - total_deferred_image_decode_time.InSecondsF()); - enumerator->AddDouble("totalImageGatheringTimeInSeconds", - total_image_gathering_time.InSecondsF()); + impl_stats.deferred_image_decode_time.InSecondsF()); enumerator->AddDouble("totalTileAnalysisTimeInSeconds", - total_tile_analysis_time.InSecondsF()); + impl_stats.tile_analysis_time.InSecondsF()); } -void RenderingStats::Add(const RenderingStats& other) { +void MainThreadRenderingStats::IssueTraceEvent() const { + TRACE_EVENT_INSTANT1("benchmark", + "MainThreadRenderingStats::IssueTraceEvent", + TRACE_EVENT_SCOPE_THREAD, + "data", AsTraceableData()); +} + +scoped_ptr<base::debug::ConvertableToTraceFormat> +MainThreadRenderingStats::AsTraceableData() const { + scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue()); + record_data->SetInteger("animation_frame_count", + animation_frame_count); + record_data->SetInteger("screen_frame_count", + screen_frame_count); + record_data->SetDouble("paint_time", + paint_time.InSecondsF()); + record_data->SetDouble("record_time", + record_time.InSecondsF()); + record_data->SetDouble("commit_time", + commit_time.InSecondsF()); + record_data->SetInteger("commit_count", + commit_count); + record_data->SetInteger("painted_pixel_count", + painted_pixel_count); + record_data->SetInteger("recorded_pixel_count", + recorded_pixel_count); + record_data->SetInteger("image_gathering_count", + image_gathering_count); + record_data->SetDouble("image_gathering_time", + image_gathering_time.InSecondsF()); + return TracedValue::FromValue(record_data.release()); +} + +void ImplThreadRenderingStats::IssueTraceEvent() const { + TRACE_EVENT_INSTANT1("benchmark", + "ImplThreadRenderingStats::IssueTraceEvent", + TRACE_EVENT_SCOPE_THREAD, + "data", AsTraceableData()); +} + +scoped_ptr<base::debug::ConvertableToTraceFormat> +ImplThreadRenderingStats::AsTraceableData() const { + scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue()); + record_data->SetInteger("screen_frame_count", + screen_frame_count); + record_data->SetInteger("dropped_frame_count", + dropped_frame_count); + record_data->SetDouble("rasterize_time", + rasterize_time.InSecondsF()); + record_data->SetDouble( + "rasterize_time_for_now_bins_on_pending_tree", + rasterize_time_for_now_bins_on_pending_tree.InSecondsF()); + record_data->SetDouble("best_rasterize_time", + best_rasterize_time.InSecondsF()); + record_data->SetInteger("rasterized_pixel_count", + rasterized_pixel_count); + record_data->SetInteger("impl_thread_scroll_count", + impl_thread_scroll_count); + record_data->SetInteger("main_thread_scroll_count", + main_thread_scroll_count); + record_data->SetInteger("drawn_layer_count", + drawn_layer_count); + record_data->SetInteger("missing_tile_count", + missing_tile_count); + record_data->SetInteger("deferred_image_decode_count", + deferred_image_decode_count); + record_data->SetInteger("deferred_image_cache_hit_count", + deferred_image_cache_hit_count); + record_data->SetInteger("tile_analysis_count", + tile_analysis_count); + record_data->SetInteger("solid_color_tile_analysis_count", + solid_color_tile_analysis_count); + record_data->SetDouble("deferred_image_decode_time", + deferred_image_decode_time.InSecondsF()); + record_data->SetDouble("tile_analysis_time", + tile_analysis_time.InSecondsF()); + return TracedValue::FromValue(record_data.release()); +} + + +void MainThreadRenderingStats::Add(const MainThreadRenderingStats& other) { animation_frame_count += other.animation_frame_count; screen_frame_count += other.screen_frame_count; + paint_time += other.paint_time; + record_time += other.record_time; + commit_time += other.commit_time; + commit_count += other.commit_count; + painted_pixel_count += other.painted_pixel_count; + recorded_pixel_count += other.recorded_pixel_count; + image_gathering_count += other.image_gathering_count; + image_gathering_time += other.image_gathering_time; +} + +void ImplThreadRenderingStats::Add(const ImplThreadRenderingStats& other) { + screen_frame_count += other.screen_frame_count; dropped_frame_count += other.dropped_frame_count; - total_paint_time += other.total_paint_time; - total_record_time += other.total_record_time; - total_rasterize_time += other.total_rasterize_time; - total_rasterize_time_for_now_bins_on_pending_tree += - other.total_rasterize_time_for_now_bins_on_pending_tree; - total_commit_time += other.total_commit_time; + rasterize_time += other.rasterize_time; + rasterize_time_for_now_bins_on_pending_tree += + other.rasterize_time_for_now_bins_on_pending_tree; best_rasterize_time += other.best_rasterize_time; - total_commit_count += other.total_commit_count; - total_pixels_painted += other.total_pixels_painted; - total_pixels_recorded += other.total_pixels_recorded; - total_pixels_rasterized += other.total_pixels_rasterized; - num_impl_thread_scrolls += other.num_impl_thread_scrolls; - num_main_thread_scrolls += other.num_main_thread_scrolls; - num_layers_drawn += other.num_layers_drawn; - num_missing_tiles += other.num_missing_tiles; - total_deferred_image_decode_count += other.total_deferred_image_decode_count; - total_deferred_image_cache_hit_count += - other.total_deferred_image_cache_hit_count; - total_image_gathering_count += other.total_image_gathering_count; - total_deferred_image_decode_time += other.total_deferred_image_decode_time; - total_image_gathering_time += other.total_image_gathering_time; - total_tiles_analyzed += other.total_tiles_analyzed; - solid_color_tiles_analyzed += other.solid_color_tiles_analyzed; - total_tile_analysis_time += other.total_tile_analysis_time; + rasterized_pixel_count += other.rasterized_pixel_count; + impl_thread_scroll_count += other.impl_thread_scroll_count; + main_thread_scroll_count += other.main_thread_scroll_count; + drawn_layer_count += other.drawn_layer_count; + missing_tile_count += other.missing_tile_count; + deferred_image_decode_count += other.deferred_image_decode_count; + deferred_image_cache_hit_count += other.deferred_image_cache_hit_count; + deferred_image_decode_time += other.deferred_image_decode_time; + tile_analysis_count += other.tile_analysis_count; + solid_color_tile_analysis_count += other.solid_color_tile_analysis_count; + tile_analysis_time += other.tile_analysis_time; +} + +void RenderingStats::Add(const RenderingStats& other) { + main_stats.Add(other.main_stats); + impl_stats.Add(other.impl_stats); } } // namespace cc diff --git a/chromium/cc/debug/rendering_stats.h b/chromium/cc/debug/rendering_stats.h index eb01a571b11..ee13706034a 100644 --- a/chromium/cc/debug/rendering_stats.h +++ b/chromium/cc/debug/rendering_stats.h @@ -8,55 +8,79 @@ #include "base/basictypes.h" #include "base/time/time.h" #include "cc/base/cc_export.h" +#include "cc/debug/traced_value.h" namespace cc { -struct CC_EXPORT RenderingStats { +// In conjunction with EnumerateFields, this allows the embedder to +// enumerate the values in this structure without +// having to embed references to its specific member variables. This +// simplifies the addition of new fields to this type. +class RenderingStatsEnumerator { + public: + virtual void AddInt64(const char* name, int64 value) = 0; + virtual void AddDouble(const char* name, double value) = 0; + virtual void AddInt(const char* name, int value) = 0; + virtual void AddTimeDeltaInSecondsF(const char* name, + const base::TimeDelta& value) = 0; + + protected: + virtual ~RenderingStatsEnumerator() {} +}; + +struct CC_EXPORT MainThreadRenderingStats { + // Note: when adding new members, please remember to update EnumerateFields + // and Add in rendering_stats.cc. + int64 animation_frame_count; int64 screen_frame_count; - int64 dropped_frame_count; - base::TimeDelta total_paint_time; - base::TimeDelta total_record_time; - base::TimeDelta total_rasterize_time; - base::TimeDelta total_rasterize_time_for_now_bins_on_pending_tree; - base::TimeDelta total_commit_time; - base::TimeDelta best_rasterize_time; - int64 total_commit_count; - int64 total_pixels_painted; - int64 total_pixels_recorded; - int64 total_pixels_rasterized; - int64 num_impl_thread_scrolls; - int64 num_main_thread_scrolls; - int64 num_layers_drawn; - int64 num_missing_tiles; - int64 total_deferred_image_decode_count; - int64 total_deferred_image_cache_hit_count; - int64 total_image_gathering_count; - int64 total_tiles_analyzed; - int64 solid_color_tiles_analyzed; - base::TimeDelta total_deferred_image_decode_time; - base::TimeDelta total_image_gathering_time; - base::TimeDelta total_tile_analysis_time; + base::TimeDelta paint_time; + base::TimeDelta record_time; + base::TimeDelta commit_time; + int64 commit_count; + int64 painted_pixel_count; + int64 recorded_pixel_count; + int64 image_gathering_count; + base::TimeDelta image_gathering_time; + + MainThreadRenderingStats(); + void IssueTraceEvent() const; + scoped_ptr<base::debug::ConvertableToTraceFormat> AsTraceableData() const; + void Add(const MainThreadRenderingStats& other); +}; + +struct CC_EXPORT ImplThreadRenderingStats { // Note: when adding new members, please remember to update EnumerateFields // and Add in rendering_stats.cc. - RenderingStats(); - - // In conjunction with EnumerateFields, this allows the embedder to - // enumerate the values in this structure without - // having to embed references to its specific member variables. This - // simplifies the addition of new fields to this type. - class Enumerator { - public: - virtual void AddInt64(const char* name, int64 value) = 0; - virtual void AddDouble(const char* name, double value) = 0; - virtual void AddInt(const char* name, int value) = 0; - virtual void AddTimeDeltaInSecondsF(const char* name, - const base::TimeDelta& value) = 0; - - protected: - virtual ~Enumerator() {} - }; + int64 screen_frame_count; + int64 dropped_frame_count; + base::TimeDelta rasterize_time; + base::TimeDelta rasterize_time_for_now_bins_on_pending_tree; + base::TimeDelta best_rasterize_time; + int64 rasterized_pixel_count; + int64 impl_thread_scroll_count; + int64 main_thread_scroll_count; + int64 drawn_layer_count; + int64 missing_tile_count; + int64 deferred_image_decode_count; + int64 deferred_image_cache_hit_count; + int64 tile_analysis_count; + int64 solid_color_tile_analysis_count; + base::TimeDelta deferred_image_decode_time; + base::TimeDelta tile_analysis_time; + + ImplThreadRenderingStats(); + void IssueTraceEvent() const; + scoped_ptr<base::debug::ConvertableToTraceFormat> AsTraceableData() const; + void Add(const ImplThreadRenderingStats& other); +}; + +struct CC_EXPORT RenderingStats { + typedef RenderingStatsEnumerator Enumerator; + + MainThreadRenderingStats main_stats; + ImplThreadRenderingStats impl_stats; // Outputs the fields in this structure to the provided enumerator. void EnumerateFields(Enumerator* enumerator) const; diff --git a/chromium/cc/debug/rendering_stats_instrumentation.cc b/chromium/cc/debug/rendering_stats_instrumentation.cc index b3886af51c0..3c2c96b8b00 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.cc +++ b/chromium/cc/debug/rendering_stats_instrumentation.cc @@ -20,19 +20,40 @@ RenderingStatsInstrumentation::~RenderingStatsInstrumentation() {} RenderingStats RenderingStatsInstrumentation::GetRenderingStats() { base::AutoLock scoped_lock(lock_); - return rendering_stats_; + RenderingStats rendering_stats; + rendering_stats.main_stats = main_stats_accu_; + rendering_stats.main_stats.Add(main_stats_); + rendering_stats.impl_stats = impl_stats_accu_; + rendering_stats.impl_stats.Add(impl_stats_); + return rendering_stats; +} + +void RenderingStatsInstrumentation::AccumulateAndClearMainThreadStats() { + main_stats_accu_.Add(main_stats_); + main_stats_ = MainThreadRenderingStats(); +} + +void RenderingStatsInstrumentation::AccumulateAndClearImplThreadStats() { + impl_stats_accu_.Add(impl_stats_); + impl_stats_ = ImplThreadRenderingStats(); } base::TimeTicks RenderingStatsInstrumentation::StartRecording() const { - if (record_rendering_stats_) + if (record_rendering_stats_) { + if (base::TimeTicks::IsThreadNowSupported()) + return base::TimeTicks::ThreadNow(); return base::TimeTicks::HighResNow(); + } return base::TimeTicks(); } base::TimeDelta RenderingStatsInstrumentation::EndRecording( base::TimeTicks start_time) const { - if (!start_time.is_null()) + if (!start_time.is_null()) { + if (base::TimeTicks::IsThreadNowSupported()) + return base::TimeTicks::ThreadNow() - start_time; return base::TimeTicks::HighResNow() - start_time; + } return base::TimeDelta(); } @@ -41,23 +62,27 @@ void RenderingStatsInstrumentation::IncrementAnimationFrameCount() { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.animation_frame_count++; + main_stats_.animation_frame_count++; } -void RenderingStatsInstrumentation::SetScreenFrameCount(int64 count) { +void RenderingStatsInstrumentation::IncrementScreenFrameCount( + int64 count, bool main_thread) { if (!record_rendering_stats_) return; base::AutoLock scoped_lock(lock_); - rendering_stats_.screen_frame_count = count; + if (main_thread) + main_stats_.screen_frame_count += count; + else + impl_stats_.screen_frame_count += count; } -void RenderingStatsInstrumentation::SetDroppedFrameCount(int64 count) { +void RenderingStatsInstrumentation::IncrementDroppedFrameCount(int64 count) { if (!record_rendering_stats_) return; base::AutoLock scoped_lock(lock_); - rendering_stats_.dropped_frame_count = count; + impl_stats_.dropped_frame_count += count; } void RenderingStatsInstrumentation::AddCommit(base::TimeDelta duration) { @@ -65,8 +90,8 @@ void RenderingStatsInstrumentation::AddCommit(base::TimeDelta duration) { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_commit_time += duration; - rendering_stats_.total_commit_count++; + main_stats_.commit_time += duration; + main_stats_.commit_count++; } void RenderingStatsInstrumentation::AddPaint(base::TimeDelta duration, @@ -75,8 +100,8 @@ void RenderingStatsInstrumentation::AddPaint(base::TimeDelta duration, return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_paint_time += duration; - rendering_stats_.total_pixels_painted += pixels; + main_stats_.paint_time += duration; + main_stats_.painted_pixel_count += pixels; } void RenderingStatsInstrumentation::AddRecord(base::TimeDelta duration, @@ -85,8 +110,8 @@ void RenderingStatsInstrumentation::AddRecord(base::TimeDelta duration, return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_record_time += duration; - rendering_stats_.total_pixels_recorded += pixels; + main_stats_.record_time += duration; + main_stats_.recorded_pixel_count += pixels; } void RenderingStatsInstrumentation::AddRaster(base::TimeDelta total_duration, @@ -97,12 +122,12 @@ void RenderingStatsInstrumentation::AddRaster(base::TimeDelta total_duration, return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_rasterize_time += total_duration; - rendering_stats_.best_rasterize_time += best_duration; - rendering_stats_.total_pixels_rasterized += pixels; + impl_stats_.rasterize_time += total_duration; + impl_stats_.best_rasterize_time += best_duration; + impl_stats_.rasterized_pixel_count += pixels; if (is_in_pending_tree_now_bin) { - rendering_stats_.total_rasterize_time_for_now_bins_on_pending_tree += + impl_stats_.rasterize_time_for_now_bins_on_pending_tree += total_duration; } } @@ -112,7 +137,7 @@ void RenderingStatsInstrumentation::IncrementImplThreadScrolls() { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.num_impl_thread_scrolls++; + impl_stats_.impl_thread_scroll_count++; } void RenderingStatsInstrumentation::IncrementMainThreadScrolls() { @@ -120,7 +145,7 @@ void RenderingStatsInstrumentation::IncrementMainThreadScrolls() { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.num_main_thread_scrolls++; + impl_stats_.main_thread_scroll_count++; } void RenderingStatsInstrumentation::AddLayersDrawn(int64 amount) { @@ -128,7 +153,7 @@ void RenderingStatsInstrumentation::AddLayersDrawn(int64 amount) { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.num_layers_drawn += amount; + impl_stats_.drawn_layer_count += amount; } void RenderingStatsInstrumentation::AddMissingTiles(int64 amount) { @@ -136,7 +161,7 @@ void RenderingStatsInstrumentation::AddMissingTiles(int64 amount) { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.num_missing_tiles += amount; + impl_stats_.missing_tile_count += amount; } void RenderingStatsInstrumentation::AddDeferredImageDecode( @@ -145,8 +170,8 @@ void RenderingStatsInstrumentation::AddDeferredImageDecode( return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_deferred_image_decode_time += duration; - rendering_stats_.total_deferred_image_decode_count++; + impl_stats_.deferred_image_decode_time += duration; + impl_stats_.deferred_image_decode_count++; } void RenderingStatsInstrumentation::AddImageGathering( @@ -155,8 +180,8 @@ void RenderingStatsInstrumentation::AddImageGathering( return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_image_gathering_time += duration; - rendering_stats_.total_image_gathering_count++; + main_stats_.image_gathering_time += duration; + main_stats_.image_gathering_count++; } void RenderingStatsInstrumentation::IncrementDeferredImageCacheHitCount() { @@ -164,7 +189,7 @@ void RenderingStatsInstrumentation::IncrementDeferredImageCacheHitCount() { return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_deferred_image_cache_hit_count++; + impl_stats_.deferred_image_cache_hit_count++; } void RenderingStatsInstrumentation::AddAnalysisResult( @@ -174,10 +199,10 @@ void RenderingStatsInstrumentation::AddAnalysisResult( return; base::AutoLock scoped_lock(lock_); - rendering_stats_.total_tiles_analyzed++; - rendering_stats_.total_tile_analysis_time += duration; + impl_stats_.tile_analysis_count++; + impl_stats_.tile_analysis_time += duration; if (is_solid_color) - rendering_stats_.solid_color_tiles_analyzed++; + impl_stats_.solid_color_tile_analysis_count++; } } // namespace cc diff --git a/chromium/cc/debug/rendering_stats_instrumentation.h b/chromium/cc/debug/rendering_stats_instrumentation.h index 6f7515a9418..5f74f9e6132 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.h +++ b/chromium/cc/debug/rendering_stats_instrumentation.h @@ -18,8 +18,33 @@ class CC_EXPORT RenderingStatsInstrumentation { static scoped_ptr<RenderingStatsInstrumentation> Create(); virtual ~RenderingStatsInstrumentation(); + // Return current main thread rendering stats. + MainThreadRenderingStats GetMainThreadRenderingStats() { + return main_stats_; + } + // Return current impl thread rendering stats. + ImplThreadRenderingStats GetImplThreadRenderingStats() { + return impl_stats_; + } + // Return the accumulated, combined rendering stats. RenderingStats GetRenderingStats(); + // Add current main thread rendering stats to accumulator and + // clear current stats. + void AccumulateAndClearMainThreadStats(); + // Add current impl thread rendering stats to accumulator and + // clear current stats. + void AccumulateAndClearImplThreadStats(); + + // Issue trace event for current main thread rendering stats. + void IssueTraceEventForMainThreadStats() { + main_stats_.IssueTraceEvent(); + } + // Issue trace event for current impl thread rendering stats. + void IssueTraceEventForImplThreadStats() { + impl_stats_.IssueTraceEvent(); + } + // Read and write access to the record_rendering_stats_ flag is not locked to // improve performance. The flag is commonly turned off and hardly changes // it's value during runtime. @@ -33,8 +58,8 @@ class CC_EXPORT RenderingStatsInstrumentation { base::TimeDelta EndRecording(base::TimeTicks start_time) const; void IncrementAnimationFrameCount(); - void SetScreenFrameCount(int64 count); - void SetDroppedFrameCount(int64 count); + void IncrementScreenFrameCount(int64 count, bool main_thread); + void IncrementDroppedFrameCount(int64 count); void AddCommit(base::TimeDelta duration); void AddPaint(base::TimeDelta duration, int64 pixels); @@ -61,7 +86,11 @@ class CC_EXPORT RenderingStatsInstrumentation { RenderingStatsInstrumentation(); private: - RenderingStats rendering_stats_; + MainThreadRenderingStats main_stats_; + MainThreadRenderingStats main_stats_accu_; + ImplThreadRenderingStats impl_stats_; + ImplThreadRenderingStats impl_stats_accu_; + bool record_rendering_stats_; base::Lock lock_; diff --git a/chromium/cc/debug/test_context_provider.cc b/chromium/cc/debug/test_context_provider.cc new file mode 100644 index 00000000000..d09ecd86ed9 --- /dev/null +++ b/chromium/cc/debug/test_context_provider.cc @@ -0,0 +1,240 @@ +// Copyright 2013 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 "cc/debug/test_context_provider.h" + +#include <set> +#include <vector> + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "base/strings/string_split.h" +#include "cc/debug/test_web_graphics_context_3d.h" + +namespace cc { + +class TestContextProvider::LostContextCallbackProxy + : public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { + public: + explicit LostContextCallbackProxy(TestContextProvider* provider) + : provider_(provider) { + provider_->context3d_->setContextLostCallback(this); + } + + virtual ~LostContextCallbackProxy() { + provider_->context3d_->setContextLostCallback(NULL); + } + + virtual void onContextLost() { + provider_->OnLostContext(); + } + + private: + TestContextProvider* provider_; +}; + +class TestContextProvider::SwapBuffersCompleteCallbackProxy + : public WebKit::WebGraphicsContext3D:: + WebGraphicsSwapBuffersCompleteCallbackCHROMIUM { + public: + explicit SwapBuffersCompleteCallbackProxy(TestContextProvider* provider) + : provider_(provider) { + provider_->context3d_->setSwapBuffersCompleteCallbackCHROMIUM(this); + } + + virtual ~SwapBuffersCompleteCallbackProxy() { + provider_->context3d_->setSwapBuffersCompleteCallbackCHROMIUM(NULL); + } + + virtual void onSwapBuffersComplete() { + provider_->OnSwapBuffersComplete(); + } + + private: + TestContextProvider* provider_; +}; + +// static +scoped_refptr<TestContextProvider> TestContextProvider::Create() { + return Create(TestWebGraphicsContext3D::Create().Pass()); +} + +// static +scoped_refptr<TestContextProvider> TestContextProvider::Create( + const CreateCallback& create_callback) { + scoped_refptr<TestContextProvider> provider = new TestContextProvider; + if (!provider->InitializeOnMainThread(create_callback)) + return NULL; + return provider; +} + +scoped_ptr<TestWebGraphicsContext3D> ReturnScopedContext( + scoped_ptr<TestWebGraphicsContext3D> context) { + return context.Pass(); +} + +// static +scoped_refptr<TestContextProvider> TestContextProvider::Create( + scoped_ptr<TestWebGraphicsContext3D> context) { + return Create(base::Bind(&ReturnScopedContext, base::Passed(&context))); +} + +TestContextProvider::TestContextProvider() + : bound_(false), + destroyed_(false) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + context_thread_checker_.DetachFromThread(); +} + +TestContextProvider::~TestContextProvider() { + DCHECK(main_thread_checker_.CalledOnValidThread() || + context_thread_checker_.CalledOnValidThread()); +} + +bool TestContextProvider::InitializeOnMainThread( + const CreateCallback& create_callback) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + DCHECK(!context3d_); + DCHECK(!create_callback.is_null()); + context3d_ = create_callback.Run(); + return context3d_; +} + +bool TestContextProvider::BindToCurrentThread() { + DCHECK(context3d_); + + // This is called on the thread the context will be used. + DCHECK(context_thread_checker_.CalledOnValidThread()); + + if (bound_) + return true; + + bound_ = true; + if (!context3d_->makeContextCurrent()) { + base::AutoLock lock(destroyed_lock_); + destroyed_ = true; + return false; + } + + lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); + swap_buffers_complete_callback_proxy_.reset( + new SwapBuffersCompleteCallbackProxy(this)); + + return true; +} + +ContextProvider::Capabilities TestContextProvider::ContextCapabilities() { + DCHECK(context3d_); + DCHECK(bound_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context3d_->test_capabilities(); +} + +WebKit::WebGraphicsContext3D* TestContextProvider::Context3d() { + DCHECK(context3d_); + DCHECK(bound_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context3d_.get(); +} + +class GrContext* TestContextProvider::GrContext() { + DCHECK(context3d_); + DCHECK(bound_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + // TODO(danakj): Make a test GrContext that works with a test Context3d. + return NULL; +} + +void TestContextProvider::VerifyContexts() { + DCHECK(context3d_); + DCHECK(bound_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + if (context3d_->isContextLost()) { + base::AutoLock lock(destroyed_lock_); + destroyed_ = true; + } +} + +bool TestContextProvider::DestroyedOnMainThread() { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + base::AutoLock lock(destroyed_lock_); + return destroyed_; +} + +void TestContextProvider::OnLostContext() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + { + base::AutoLock lock(destroyed_lock_); + if (destroyed_) + return; + destroyed_ = true; + } + if (!lost_context_callback_.is_null()) + base::ResetAndReturn(&lost_context_callback_).Run(); +} + +void TestContextProvider::OnSwapBuffersComplete() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + if (!swap_buffers_complete_callback_.is_null()) + swap_buffers_complete_callback_.Run(); +} + +TestWebGraphicsContext3D* TestContextProvider::TestContext3d() { + DCHECK(context3d_); + DCHECK(bound_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context3d_.get(); +} + +TestWebGraphicsContext3D* TestContextProvider::UnboundTestContext3d() { + DCHECK(context3d_); + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context3d_.get(); +} + +void TestContextProvider::SetMemoryAllocation( + const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) { + if (memory_policy_changed_callback_.is_null()) + return; + memory_policy_changed_callback_.Run( + policy, discard_backbuffer_when_not_visible); +} + +void TestContextProvider::SetLostContextCallback( + const LostContextCallback& cb) { + DCHECK(context_thread_checker_.CalledOnValidThread()); + DCHECK(lost_context_callback_.is_null() || cb.is_null()); + lost_context_callback_ = cb; +} + +void TestContextProvider::SetSwapBuffersCompleteCallback( + const SwapBuffersCompleteCallback& cb) { + DCHECK(context_thread_checker_.CalledOnValidThread()); + DCHECK(swap_buffers_complete_callback_.is_null() || cb.is_null()); + swap_buffers_complete_callback_ = cb; +} + +void TestContextProvider::SetMemoryPolicyChangedCallback( + const MemoryPolicyChangedCallback& cb) { + DCHECK(context_thread_checker_.CalledOnValidThread()); + DCHECK(memory_policy_changed_callback_.is_null() || cb.is_null()); + memory_policy_changed_callback_ = cb; +} + +void TestContextProvider::SetMaxTransferBufferUsageBytes( + size_t max_transfer_buffer_usage_bytes) { + context3d_->SetMaxTransferBufferUsageBytes(max_transfer_buffer_usage_bytes); +} + +} // namespace cc diff --git a/chromium/cc/debug/test_context_provider.h b/chromium/cc/debug/test_context_provider.h new file mode 100644 index 00000000000..0401fcf1ba8 --- /dev/null +++ b/chromium/cc/debug/test_context_provider.h @@ -0,0 +1,90 @@ +// Copyright 2013 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. + +#ifndef CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ +#define CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" +#include "cc/base/cc_export.h" +#include "cc/output/context_provider.h" + +namespace WebKit { class WebGraphicsContext3D; } + +namespace cc { +class TestWebGraphicsContext3D; + +class CC_EXPORT TestContextProvider + : public NON_EXPORTED_BASE(cc::ContextProvider) { + public: + typedef base::Callback<scoped_ptr<TestWebGraphicsContext3D>(void)> + CreateCallback; + + static scoped_refptr<TestContextProvider> Create(); + static scoped_refptr<TestContextProvider> Create( + const CreateCallback& create_callback); + static scoped_refptr<TestContextProvider> Create( + scoped_ptr<TestWebGraphicsContext3D> context); + + virtual bool BindToCurrentThread() OVERRIDE; + virtual Capabilities ContextCapabilities() OVERRIDE; + virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; + virtual class GrContext* GrContext() OVERRIDE; + virtual void VerifyContexts() OVERRIDE; + virtual bool DestroyedOnMainThread() OVERRIDE; + virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE; + virtual void SetSwapBuffersCompleteCallback( + const SwapBuffersCompleteCallback& cb) OVERRIDE; + virtual void SetMemoryPolicyChangedCallback( + const MemoryPolicyChangedCallback& cb) OVERRIDE; + + TestWebGraphicsContext3D* TestContext3d(); + + // This returns the TestWebGraphicsContext3D but is valid to call + // before the context is bound to a thread. This is needed to set up + // state on the test context before binding. Don't call + // makeContextCurrent on the context returned from this method. + TestWebGraphicsContext3D* UnboundTestContext3d(); + + void SetMemoryAllocation(const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible); + + void SetMaxTransferBufferUsageBytes(size_t max_transfer_buffer_usage_bytes); + + protected: + TestContextProvider(); + virtual ~TestContextProvider(); + + bool InitializeOnMainThread(const CreateCallback& create_callback); + + void OnLostContext(); + void OnSwapBuffersComplete(); + + scoped_ptr<TestWebGraphicsContext3D> context3d_; + bool bound_; + + base::ThreadChecker main_thread_checker_; + base::ThreadChecker context_thread_checker_; + + base::Lock destroyed_lock_; + bool destroyed_; + + LostContextCallback lost_context_callback_; + SwapBuffersCompleteCallback swap_buffers_complete_callback_; + MemoryPolicyChangedCallback memory_policy_changed_callback_; + + class LostContextCallbackProxy; + scoped_ptr<LostContextCallbackProxy> lost_context_callback_proxy_; + + class SwapBuffersCompleteCallbackProxy; + scoped_ptr<SwapBuffersCompleteCallbackProxy> + swap_buffers_complete_callback_proxy_; +}; + +} // namespace cc + +#endif // CC_DEBUG_TEST_CONTEXT_PROVIDER_H_ + diff --git a/chromium/cc/debug/test_web_graphics_context_3d.cc b/chromium/cc/debug/test_web_graphics_context_3d.cc new file mode 100644 index 00000000000..634778fc4e6 --- /dev/null +++ b/chromium/cc/debug/test_web_graphics_context_3d.cc @@ -0,0 +1,632 @@ +// Copyright 2013 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 "cc/debug/test_web_graphics_context_3d.h" + +#include <algorithm> +#include <string> + +#include "base/bind.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "gpu/GLES2/gl2extchromium.h" +#include "third_party/khronos/GLES2/gl2ext.h" + +using WebKit::WGC3Dboolean; +using WebKit::WGC3Dchar; +using WebKit::WGC3Denum; +using WebKit::WGC3Dint; +using WebKit::WGC3Dsizei; +using WebKit::WGC3Dsizeiptr; +using WebKit::WGC3Duint; +using WebKit::WebGLId; +using WebKit::WebGraphicsContext3D; + +namespace cc { + +static const WebGLId kFramebufferId = 1; +static const WebGLId kProgramId = 2; +static const WebGLId kRenderbufferId = 3; +static const WebGLId kShaderId = 4; + +static unsigned s_context_id = 1; + +const WebGLId TestWebGraphicsContext3D::kExternalTextureId = 1337; + +static base::LazyInstance<base::Lock>::Leaky + g_shared_namespace_lock = LAZY_INSTANCE_INITIALIZER; + +TestWebGraphicsContext3D::Namespace* + TestWebGraphicsContext3D::shared_namespace_ = NULL; + +TestWebGraphicsContext3D::Namespace::Namespace() + : next_buffer_id(1), + next_image_id(1), + next_texture_id(1) { +} + +TestWebGraphicsContext3D::Namespace::~Namespace() { + g_shared_namespace_lock.Get().AssertAcquired(); + if (shared_namespace_ == this) + shared_namespace_ = NULL; +} + +// static +scoped_ptr<TestWebGraphicsContext3D> TestWebGraphicsContext3D::Create() { + return make_scoped_ptr(new TestWebGraphicsContext3D()); +} + +TestWebGraphicsContext3D::TestWebGraphicsContext3D() + : FakeWebGraphicsContext3D(), + context_id_(s_context_id++), + times_make_current_succeeds_(-1), + times_bind_texture_succeeds_(-1), + times_end_query_succeeds_(-1), + times_gen_mailbox_succeeds_(-1), + context_lost_(false), + times_map_image_chromium_succeeds_(-1), + times_map_buffer_chromium_succeeds_(-1), + context_lost_callback_(NULL), + swap_buffers_callback_(NULL), + max_texture_size_(2048), + width_(0), + height_(0), + bound_buffer_(0), + weak_ptr_factory_(this) { + CreateNamespace(); + test_capabilities_.swapbuffers_complete_callback = true; +} + +TestWebGraphicsContext3D::TestWebGraphicsContext3D( + const WebGraphicsContext3D::Attributes& attributes) + : FakeWebGraphicsContext3D(), + context_id_(s_context_id++), + attributes_(attributes), + times_make_current_succeeds_(-1), + times_bind_texture_succeeds_(-1), + times_end_query_succeeds_(-1), + times_gen_mailbox_succeeds_(-1), + context_lost_(false), + times_map_image_chromium_succeeds_(-1), + times_map_buffer_chromium_succeeds_(-1), + context_lost_callback_(NULL), + swap_buffers_callback_(NULL), + max_texture_size_(2048), + width_(0), + height_(0), + bound_buffer_(0), + weak_ptr_factory_(this) { + CreateNamespace(); + test_capabilities_.swapbuffers_complete_callback = true; +} + +void TestWebGraphicsContext3D::CreateNamespace() { + if (attributes_.shareResources) { + base::AutoLock lock(g_shared_namespace_lock.Get()); + if (shared_namespace_) { + namespace_ = shared_namespace_; + } else { + namespace_ = new Namespace; + shared_namespace_ = namespace_.get(); + } + } else { + namespace_ = new Namespace; + } +} + +TestWebGraphicsContext3D::~TestWebGraphicsContext3D() { + for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) { + if (sync_point_callbacks_[i] != NULL) + delete sync_point_callbacks_[i]; + } + base::AutoLock lock(g_shared_namespace_lock.Get()); + namespace_ = NULL; +} + +bool TestWebGraphicsContext3D::makeContextCurrent() { + if (times_make_current_succeeds_ >= 0) { + if (!times_make_current_succeeds_) { + loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + } + --times_make_current_succeeds_; + } + return !context_lost_; +} + +int TestWebGraphicsContext3D::width() { + return width_; +} + +int TestWebGraphicsContext3D::height() { + return height_; +} + +void TestWebGraphicsContext3D::reshapeWithScaleFactor( + int width, int height, float scale_factor) { + width_ = width; + height_ = height; +} + +bool TestWebGraphicsContext3D::isContextLost() { + return context_lost_; +} + +WGC3Denum TestWebGraphicsContext3D::getGraphicsResetStatusARB() { + return context_lost_ ? GL_UNKNOWN_CONTEXT_RESET_ARB : GL_NO_ERROR; +} + +WGC3Denum TestWebGraphicsContext3D::checkFramebufferStatus( + WGC3Denum target) { + if (context_lost_) + return GL_FRAMEBUFFER_UNDEFINED_OES; + return GL_FRAMEBUFFER_COMPLETE; +} + +WebGraphicsContext3D::Attributes + TestWebGraphicsContext3D::getContextAttributes() { + return attributes_; +} + +WebKit::WebString TestWebGraphicsContext3D::getString(WGC3Denum name) { + return WebKit::WebString(); +} + +WGC3Dint TestWebGraphicsContext3D::getUniformLocation( + WebGLId program, + const WGC3Dchar* name) { + return 0; +} + +WGC3Dsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset( + WGC3Duint index, + WGC3Denum pname) { + return 0; +} + +WGC3Dboolean TestWebGraphicsContext3D::isBuffer( + WebGLId buffer) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isEnabled( + WGC3Denum cap) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isFramebuffer( + WebGLId framebuffer) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isProgram( + WebGLId program) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isRenderbuffer( + WebGLId renderbuffer) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isShader( + WebGLId shader) { + return false; +} + +WGC3Dboolean TestWebGraphicsContext3D::isTexture( + WebGLId texture) { + return false; +} + +WebGLId TestWebGraphicsContext3D::createBuffer() { + return NextBufferId(); +} + +void TestWebGraphicsContext3D::deleteBuffer(WebGLId id) { + base::AutoLock lock(namespace_->lock); + unsigned context_id = id >> 17; + unsigned buffer_id = id & 0x1ffff; + DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id); + DCHECK_EQ(context_id, context_id_); +} + +WebGLId TestWebGraphicsContext3D::createFramebuffer() { + return kFramebufferId | context_id_ << 16; +} + +void TestWebGraphicsContext3D::deleteFramebuffer(WebGLId id) { + DCHECK_EQ(kFramebufferId | context_id_ << 16, id); +} + +WebGLId TestWebGraphicsContext3D::createProgram() { + return kProgramId | context_id_ << 16; +} + +void TestWebGraphicsContext3D::deleteProgram(WebGLId id) { + DCHECK_EQ(kProgramId | context_id_ << 16, id); +} + +WebGLId TestWebGraphicsContext3D::createRenderbuffer() { + return kRenderbufferId | context_id_ << 16; +} + +void TestWebGraphicsContext3D::deleteRenderbuffer(WebGLId id) { + DCHECK_EQ(kRenderbufferId | context_id_ << 16, id); +} + +WebGLId TestWebGraphicsContext3D::createShader(WGC3Denum) { + return kShaderId | context_id_ << 16; +} + +void TestWebGraphicsContext3D::deleteShader(WebGLId id) { + DCHECK_EQ(kShaderId | context_id_ << 16, id); +} + +WebGLId TestWebGraphicsContext3D::createTexture() { + WebGLId texture_id = NextTextureId(); + DCHECK_NE(texture_id, kExternalTextureId); + base::AutoLock lock(namespace_->lock); + namespace_->textures.push_back(texture_id); + return texture_id; +} + +void TestWebGraphicsContext3D::deleteTexture(WebGLId texture_id) { + base::AutoLock lock(namespace_->lock); + std::vector<WebKit::WebGLId>& textures = namespace_->textures; + DCHECK(std::find(textures.begin(), textures.end(), texture_id) != + textures.end()); + textures.erase(std::find(textures.begin(), textures.end(), texture_id)); +} + +void TestWebGraphicsContext3D::attachShader(WebGLId program, WebGLId shader) { + DCHECK_EQ(kProgramId | context_id_ << 16, program); + DCHECK_EQ(kShaderId | context_id_ << 16, shader); +} + +void TestWebGraphicsContext3D::useProgram(WebGLId program) { + if (!program) + return; + DCHECK_EQ(kProgramId | context_id_ << 16, program); +} + +void TestWebGraphicsContext3D::bindFramebuffer( + WGC3Denum target, WebGLId framebuffer) { + if (!framebuffer) + return; + DCHECK_EQ(kFramebufferId | context_id_ << 16, framebuffer); +} + +void TestWebGraphicsContext3D::bindRenderbuffer( + WGC3Denum target, WebGLId renderbuffer) { + if (!renderbuffer) + return; + DCHECK_EQ(kRenderbufferId | context_id_ << 16, renderbuffer); +} + +void TestWebGraphicsContext3D::bindTexture( + WGC3Denum target, WebGLId texture_id) { + if (times_bind_texture_succeeds_ >= 0) { + if (!times_bind_texture_succeeds_) { + loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + } + --times_bind_texture_succeeds_; + } + + if (!texture_id) + return; + if (texture_id == kExternalTextureId) + return; + base::AutoLock lock(namespace_->lock); + std::vector<WebKit::WebGLId>& textures = namespace_->textures; + DCHECK(std::find(textures.begin(), textures.end(), texture_id) != + textures.end()); + used_textures_.insert(texture_id); +} + +void TestWebGraphicsContext3D::endQueryEXT(WGC3Denum target) { + if (times_end_query_succeeds_ >= 0) { + if (!times_end_query_succeeds_) { + loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + } + --times_end_query_succeeds_; + } +} + +void TestWebGraphicsContext3D::getQueryObjectuivEXT( + WebGLId query, + WGC3Denum pname, + WGC3Duint* params) { + // If the context is lost, behave as if result is available. + if (pname == GL_QUERY_RESULT_AVAILABLE_EXT) + *params = 1; +} + +void TestWebGraphicsContext3D::getIntegerv( + WGC3Denum pname, + WebKit::WGC3Dint* value) { + if (pname == GL_MAX_TEXTURE_SIZE) + *value = max_texture_size_; + else if (pname == GL_ACTIVE_TEXTURE) + *value = GL_TEXTURE0; +} + +void TestWebGraphicsContext3D::genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox) { + if (times_gen_mailbox_succeeds_ >= 0) { + if (!times_gen_mailbox_succeeds_) { + loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + } + --times_gen_mailbox_succeeds_; + } + if (context_lost_) { + memset(mailbox, 0, 64); + return; + } + + static char mailbox_name1 = '1'; + static char mailbox_name2 = '1'; + mailbox[0] = mailbox_name1; + mailbox[1] = mailbox_name2; + mailbox[2] = '\0'; + if (++mailbox_name1 == 0) { + mailbox_name1 = '1'; + ++mailbox_name2; + } +} + +void TestWebGraphicsContext3D::setContextLostCallback( + WebGraphicsContextLostCallback* callback) { + context_lost_callback_ = callback; +} + +void TestWebGraphicsContext3D::loseContextCHROMIUM(WGC3Denum current, + WGC3Denum other) { + if (context_lost_) + return; + context_lost_ = true; + if (context_lost_callback_) + context_lost_callback_->onContextLost(); + + for (size_t i = 0; i < shared_contexts_.size(); ++i) + shared_contexts_[i]->loseContextCHROMIUM(current, other); + shared_contexts_.clear(); +} + +void TestWebGraphicsContext3D::signalSyncPoint( + unsigned sync_point, + WebGraphicsSyncPointCallback* callback) { + sync_point_callbacks_.push_back(callback); +} + +void TestWebGraphicsContext3D::signalQuery( + WebKit::WebGLId query, + WebGraphicsSyncPointCallback* callback) { + sync_point_callbacks_.push_back(callback); +} + +void TestWebGraphicsContext3D::setSwapBuffersCompleteCallbackCHROMIUM( + WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback) { + if (test_capabilities_.swapbuffers_complete_callback) + swap_buffers_callback_ = callback; +} + +void TestWebGraphicsContext3D::prepareTexture() { + if (swap_buffers_callback_) { + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&TestWebGraphicsContext3D::SwapBuffersComplete, + weak_ptr_factory_.GetWeakPtr())); + } + CallAllSyncPointCallbacks(); +} + +void TestWebGraphicsContext3D::finish() { + CallAllSyncPointCallbacks(); +} + +void TestWebGraphicsContext3D::flush() { + CallAllSyncPointCallbacks(); +} + +static void CallAndDestroy( + WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback* callback) { + if (!callback) + return; + callback->onSyncPointReached(); + delete callback; +} + +void TestWebGraphicsContext3D::CallAllSyncPointCallbacks() { + for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&CallAndDestroy, + sync_point_callbacks_[i])); + } + sync_point_callbacks_.clear(); +} + +void TestWebGraphicsContext3D::SwapBuffersComplete() { + if (swap_buffers_callback_) + swap_buffers_callback_->onSwapBuffersComplete(); +} + +void TestWebGraphicsContext3D::bindBuffer(WebKit::WGC3Denum target, + WebKit::WebGLId buffer) { + bound_buffer_ = buffer; + if (!bound_buffer_) + return; + unsigned context_id = buffer >> 17; + unsigned buffer_id = buffer & 0x1ffff; + base::AutoLock lock(namespace_->lock); + DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id); + DCHECK_EQ(context_id, context_id_); + + base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; + if (buffers.count(bound_buffer_) == 0) + buffers.set(bound_buffer_, make_scoped_ptr(new Buffer).Pass()); + + buffers.get(bound_buffer_)->target = target; +} + +void TestWebGraphicsContext3D::bufferData(WebKit::WGC3Denum target, + WebKit::WGC3Dsizeiptr size, + const void* data, + WebKit::WGC3Denum usage) { + base::AutoLock lock(namespace_->lock); + base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; + DCHECK_GT(buffers.count(bound_buffer_), 0u); + DCHECK_EQ(target, buffers.get(bound_buffer_)->target); + Buffer* buffer = buffers.get(bound_buffer_); + if (context_lost_) { + buffer->pixels.reset(); + return; + } + + buffer->pixels.reset(new uint8[size]); + buffer->size = size; + if (data != NULL) + memcpy(buffer->pixels.get(), data, size); +} + +void* TestWebGraphicsContext3D::mapBufferCHROMIUM(WebKit::WGC3Denum target, + WebKit::WGC3Denum access) { + base::AutoLock lock(namespace_->lock); + base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; + DCHECK_GT(buffers.count(bound_buffer_), 0u); + DCHECK_EQ(target, buffers.get(bound_buffer_)->target); + if (times_map_buffer_chromium_succeeds_ >= 0) { + if (!times_map_buffer_chromium_succeeds_) { + return NULL; + } + --times_map_buffer_chromium_succeeds_; + } + return buffers.get(bound_buffer_)->pixels.get(); +} + +WebKit::WGC3Dboolean TestWebGraphicsContext3D::unmapBufferCHROMIUM( + WebKit::WGC3Denum target) { + base::AutoLock lock(namespace_->lock); + base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; + DCHECK_GT(buffers.count(bound_buffer_), 0u); + DCHECK_EQ(target, buffers.get(bound_buffer_)->target); + buffers.get(bound_buffer_)->pixels.reset(); + return true; +} + +WebKit::WGC3Duint TestWebGraphicsContext3D::createImageCHROMIUM( + WebKit::WGC3Dsizei width, WebKit::WGC3Dsizei height, + WebKit::WGC3Denum internalformat) { + DCHECK_EQ(GL_RGBA8_OES, static_cast<int>(internalformat)); + WebKit::WGC3Duint image_id = NextImageId(); + base::AutoLock lock(namespace_->lock); + base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; + images.set(image_id, make_scoped_ptr(new Image).Pass()); + images.get(image_id)->pixels.reset(new uint8[width * height * 4]); + return image_id; +} + +void TestWebGraphicsContext3D::destroyImageCHROMIUM( + WebKit::WGC3Duint id) { + base::AutoLock lock(namespace_->lock); + unsigned context_id = id >> 17; + unsigned image_id = id & 0x1ffff; + DCHECK(image_id && image_id < namespace_->next_image_id); + DCHECK_EQ(context_id, context_id_); +} + +void TestWebGraphicsContext3D::getImageParameterivCHROMIUM( + WebKit::WGC3Duint image_id, + WebKit::WGC3Denum pname, + WebKit::WGC3Dint* params) { + base::AutoLock lock(namespace_->lock); + DCHECK_GT(namespace_->images.count(image_id), 0u); + DCHECK_EQ(GL_IMAGE_ROWBYTES_CHROMIUM, static_cast<int>(pname)); + *params = 0; +} + +void* TestWebGraphicsContext3D::mapImageCHROMIUM(WebKit::WGC3Duint image_id, + WebKit::WGC3Denum access) { + base::AutoLock lock(namespace_->lock); + base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; + DCHECK_GT(images.count(image_id), 0u); + if (times_map_image_chromium_succeeds_ >= 0) { + if (!times_map_image_chromium_succeeds_) { + return NULL; + } + --times_map_image_chromium_succeeds_; + } + return images.get(image_id)->pixels.get(); +} + +void TestWebGraphicsContext3D::unmapImageCHROMIUM( + WebKit::WGC3Duint image_id) { + base::AutoLock lock(namespace_->lock); + DCHECK_GT(namespace_->images.count(image_id), 0u); +} + +size_t TestWebGraphicsContext3D::NumTextures() const { + base::AutoLock lock(namespace_->lock); + return namespace_->textures.size(); +} + +WebKit::WebGLId TestWebGraphicsContext3D::TextureAt(int i) const { + base::AutoLock lock(namespace_->lock); + return namespace_->textures[i]; +} + +WebGLId TestWebGraphicsContext3D::NextTextureId() { + base::AutoLock lock(namespace_->lock); + WebGLId texture_id = namespace_->next_texture_id++; + DCHECK(texture_id < (1 << 16)); + texture_id |= context_id_ << 16; + return texture_id; +} + +WebGLId TestWebGraphicsContext3D::NextBufferId() { + base::AutoLock lock(namespace_->lock); + WebGLId buffer_id = namespace_->next_buffer_id++; + DCHECK(buffer_id < (1 << 17)); + buffer_id |= context_id_ << 17; + return buffer_id; +} + +WebKit::WGC3Duint TestWebGraphicsContext3D::NextImageId() { + base::AutoLock lock(namespace_->lock); + WGC3Duint image_id = namespace_->next_image_id++; + DCHECK(image_id < (1 << 17)); + image_id |= context_id_ << 17; + return image_id; +} + +size_t TestWebGraphicsContext3D::GetTransferBufferMemoryUsedBytes() const { + size_t total_bytes = 0; + base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; + base::ScopedPtrHashMap<unsigned, Buffer>::iterator it = buffers.begin(); + for (; it != buffers.end(); ++it) { + Buffer* buffer = it->second; + if (buffer->target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) + total_bytes += buffer->size; + } + return total_bytes; +} + +void TestWebGraphicsContext3D::SetMaxTransferBufferUsageBytes( + size_t max_transfer_buffer_usage_bytes) { + test_capabilities_.max_transfer_buffer_usage_bytes = + max_transfer_buffer_usage_bytes; +} + +TestWebGraphicsContext3D::Buffer::Buffer() : target(0), size(0) {} + +TestWebGraphicsContext3D::Buffer::~Buffer() {} + +TestWebGraphicsContext3D::Image::Image() {} + +TestWebGraphicsContext3D::Image::~Image() {} + +} // namespace cc diff --git a/chromium/cc/debug/test_web_graphics_context_3d.h b/chromium/cc/debug/test_web_graphics_context_3d.h new file mode 100644 index 00000000000..4db270c4dd6 --- /dev/null +++ b/chromium/cc/debug/test_web_graphics_context_3d.h @@ -0,0 +1,292 @@ +// Copyright 2013 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. + +#ifndef CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ +#define CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ + +#include <vector> + +#include "base/compiler_specific.h" +#include "base/containers/hash_tables.h" +#include "base/containers/scoped_ptr_hash_map.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/stl_util.h" +#include "base/synchronization/lock.h" +#include "cc/base/cc_export.h" +#include "cc/debug/fake_web_graphics_context_3d.h" +#include "cc/output/context_provider.h" +#include "third_party/khronos/GLES2/gl2.h" + +namespace cc { + +class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { + public: + static scoped_ptr<TestWebGraphicsContext3D> Create(); + + virtual ~TestWebGraphicsContext3D(); + + virtual bool makeContextCurrent(); + + virtual int width(); + virtual int height(); + + virtual void reshapeWithScaleFactor( + int width, int height, float scale_factor); + + virtual bool isContextLost(); + virtual WebKit::WGC3Denum getGraphicsResetStatusARB(); + + virtual void attachShader(WebKit::WebGLId program, WebKit::WebGLId shader); + virtual void bindFramebuffer( + WebKit::WGC3Denum target, WebKit::WebGLId framebuffer); + virtual void bindRenderbuffer( + WebKit::WGC3Denum target, WebKit::WebGLId renderbuffer); + virtual void bindTexture( + WebKit::WGC3Denum target, + WebKit::WebGLId texture_id); + + virtual WebKit::WGC3Denum checkFramebufferStatus(WebKit::WGC3Denum target); + + virtual Attributes getContextAttributes(); + + virtual WebKit::WebString getString(WebKit::WGC3Denum name); + virtual WebKit::WGC3Dint getUniformLocation( + WebKit::WebGLId program, + const WebKit::WGC3Dchar* name); + virtual WebKit::WGC3Dsizeiptr getVertexAttribOffset( + WebKit::WGC3Duint index, + WebKit::WGC3Denum pname); + + virtual WebKit::WGC3Dboolean isBuffer(WebKit::WebGLId buffer); + virtual WebKit::WGC3Dboolean isEnabled(WebKit::WGC3Denum cap); + virtual WebKit::WGC3Dboolean isFramebuffer(WebKit::WebGLId framebuffer); + virtual WebKit::WGC3Dboolean isProgram(WebKit::WebGLId program); + virtual WebKit::WGC3Dboolean isRenderbuffer(WebKit::WebGLId renderbuffer); + virtual WebKit::WGC3Dboolean isShader(WebKit::WebGLId shader); + virtual WebKit::WGC3Dboolean isTexture(WebKit::WebGLId texture); + + virtual void useProgram(WebKit::WebGLId program); + + virtual WebKit::WebGLId createBuffer(); + virtual WebKit::WebGLId createFramebuffer(); + virtual WebKit::WebGLId createProgram(); + virtual WebKit::WebGLId createRenderbuffer(); + virtual WebKit::WebGLId createShader(WebKit::WGC3Denum); + virtual WebKit::WebGLId createTexture(); + + virtual void deleteBuffer(WebKit::WebGLId id); + virtual void deleteFramebuffer(WebKit::WebGLId id); + virtual void deleteProgram(WebKit::WebGLId id); + virtual void deleteRenderbuffer(WebKit::WebGLId id); + virtual void deleteShader(WebKit::WebGLId id); + virtual void deleteTexture(WebKit::WebGLId texture_id); + + virtual void endQueryEXT(WebKit::WGC3Denum target); + virtual void getQueryObjectuivEXT( + WebKit::WebGLId query, + WebKit::WGC3Denum pname, + WebKit::WGC3Duint* params); + + virtual void getIntegerv( + WebKit::WGC3Denum pname, + WebKit::WGC3Dint* value); + + virtual void genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox); + virtual void produceTextureCHROMIUM(WebKit::WGC3Denum target, + const WebKit::WGC3Dbyte* mailbox) { } + virtual void consumeTextureCHROMIUM(WebKit::WGC3Denum target, + const WebKit::WGC3Dbyte* mailbox) { } + + virtual void setContextLostCallback( + WebGraphicsContextLostCallback* callback); + + virtual void loseContextCHROMIUM(WebKit::WGC3Denum current, + WebKit::WGC3Denum other); + + // Takes ownership of the |callback|. + virtual void signalSyncPoint(unsigned sync_point, + WebGraphicsSyncPointCallback* callback); + virtual void signalQuery(WebKit::WebGLId query, + WebGraphicsSyncPointCallback* callback); + + virtual void setSwapBuffersCompleteCallbackCHROMIUM( + WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback); + + virtual void prepareTexture(); + virtual void finish(); + virtual void flush(); + + virtual void bindBuffer(WebKit::WGC3Denum target, WebKit::WebGLId buffer); + virtual void bufferData(WebKit::WGC3Denum target, + WebKit::WGC3Dsizeiptr size, + const void* data, + WebKit::WGC3Denum usage); + virtual void* mapBufferCHROMIUM(WebKit::WGC3Denum target, + WebKit::WGC3Denum access); + virtual WebKit::WGC3Dboolean unmapBufferCHROMIUM(WebKit::WGC3Denum target); + + virtual WebKit::WGC3Duint createImageCHROMIUM( + WebKit::WGC3Dsizei width, + WebKit::WGC3Dsizei height, + WebKit::WGC3Denum internalformat); + virtual void destroyImageCHROMIUM(WebKit::WGC3Duint image_id); + virtual void getImageParameterivCHROMIUM( + WebKit::WGC3Duint image_id, + WebKit::WGC3Denum pname, + WebKit::WGC3Dint* params); + virtual void* mapImageCHROMIUM( + WebKit::WGC3Duint image_id, + WebKit::WGC3Denum access); + virtual void unmapImageCHROMIUM(WebKit::WGC3Duint image_id); + + const ContextProvider::Capabilities& test_capabilities() const { + return test_capabilities_; + } + + // When set, MakeCurrent() will fail after this many times. + void set_times_make_current_succeeds(int times) { + times_make_current_succeeds_ = times; + } + void set_times_bind_texture_succeeds(int times) { + times_bind_texture_succeeds_ = times; + } + void set_times_end_query_succeeds(int times) { + times_end_query_succeeds_ = times; + } + void set_times_gen_mailbox_succeeds(int times) { + times_gen_mailbox_succeeds_ = times; + } + + // When set, mapImageCHROMIUM and mapBufferCHROMIUM will return NULL after + // this many times. + void set_times_map_image_chromium_succeeds(int times) { + times_map_image_chromium_succeeds_ = times; + } + void set_times_map_buffer_chromium_succeeds(int times) { + times_map_buffer_chromium_succeeds_ = times; + } + + size_t NumTextures() const; + WebKit::WebGLId TextureAt(int i) const; + + size_t NumUsedTextures() const { return used_textures_.size(); } + bool UsedTexture(int texture) const { + return ContainsKey(used_textures_, texture); + } + void ResetUsedTextures() { used_textures_.clear(); } + + void set_support_swapbuffers_complete_callback(bool support) { + test_capabilities_.swapbuffers_complete_callback = support; + } + void set_have_extension_io_surface(bool have) { + test_capabilities_.iosurface = have; + } + void set_have_extension_egl_image(bool have) { + test_capabilities_.egl_image_external = have; + } + void set_have_post_sub_buffer(bool have) { + test_capabilities_.post_sub_buffer = have; + } + void set_have_discard_framebuffer(bool have) { + test_capabilities_.discard_framebuffer = have; + } + + // When this context is lost, all contexts in its share group are also lost. + void add_share_group_context(WebKit::WebGraphicsContext3D* context3d) { + shared_contexts_.push_back(context3d); + } + + void set_max_texture_size(int size) { max_texture_size_ = size; } + + static const WebKit::WebGLId kExternalTextureId; + virtual WebKit::WebGLId NextTextureId(); + + virtual WebKit::WebGLId NextBufferId(); + + virtual WebKit::WebGLId NextImageId(); + + size_t GetTransferBufferMemoryUsedBytes() const; + void SetMaxTransferBufferUsageBytes(size_t max_transfer_buffer_usage_bytes); + + protected: + struct Buffer { + Buffer(); + ~Buffer(); + + WebKit::WGC3Denum target; + scoped_ptr<uint8[]> pixels; + size_t size; + + private: + DISALLOW_COPY_AND_ASSIGN(Buffer); + }; + + struct Image { + Image(); + ~Image(); + + scoped_ptr<uint8[]> pixels; + + private: + DISALLOW_COPY_AND_ASSIGN(Image); + }; + + struct Namespace : public base::RefCountedThreadSafe<Namespace> { + Namespace(); + + // Protects all fields. + base::Lock lock; + unsigned next_buffer_id; + unsigned next_image_id; + unsigned next_texture_id; + std::vector<WebKit::WebGLId> textures; + base::ScopedPtrHashMap<unsigned, Buffer> buffers; + base::ScopedPtrHashMap<unsigned, Image> images; + + private: + friend class base::RefCountedThreadSafe<Namespace>; + ~Namespace(); + DISALLOW_COPY_AND_ASSIGN(Namespace); + }; + + TestWebGraphicsContext3D(); + TestWebGraphicsContext3D( + const WebKit::WebGraphicsContext3D::Attributes& attributes); + + void CallAllSyncPointCallbacks(); + void SwapBuffersComplete(); + void CreateNamespace(); + + unsigned context_id_; + Attributes attributes_; + ContextProvider::Capabilities test_capabilities_; + int times_make_current_succeeds_; + int times_bind_texture_succeeds_; + int times_end_query_succeeds_; + int times_gen_mailbox_succeeds_; + bool context_lost_; + int times_map_image_chromium_succeeds_; + int times_map_buffer_chromium_succeeds_; + WebGraphicsContextLostCallback* context_lost_callback_; + WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* swap_buffers_callback_; + std::vector<WebGraphicsSyncPointCallback*> sync_point_callbacks_; + base::hash_set<WebKit::WebGLId> used_textures_; + std::vector<WebKit::WebGraphicsContext3D*> shared_contexts_; + int max_texture_size_; + int width_; + int height_; + + unsigned bound_buffer_; + + scoped_refptr<Namespace> namespace_; + static Namespace* shared_namespace_; + + base::WeakPtrFactory<TestWebGraphicsContext3D> weak_ptr_factory_; +}; + +} // namespace cc + +#endif // CC_DEBUG_TEST_WEB_GRAPHICS_CONTEXT_3D_H_ diff --git a/chromium/cc/debug/traced_picture.cc b/chromium/cc/debug/traced_picture.cc index 7f04d0d783f..0cc2148f5f0 100644 --- a/chromium/cc/debug/traced_picture.cc +++ b/chromium/cc/debug/traced_picture.cc @@ -12,7 +12,8 @@ namespace cc { TracedPicture::TracedPicture(scoped_refptr<Picture> picture) - : picture_(picture) { + : picture_(picture), + is_alias_(false) { } TracedPicture::~TracedPicture() { @@ -25,7 +26,34 @@ scoped_ptr<base::debug::ConvertableToTraceFormat> return result.PassAs<base::debug::ConvertableToTraceFormat>(); } +scoped_ptr<base::debug::ConvertableToTraceFormat> + TracedPicture::AsTraceablePictureAlias(Picture* original) { + TracedPicture* ptr = new TracedPicture(original); + ptr->is_alias_ = true; + scoped_ptr<TracedPicture> result(ptr); + return result.PassAs<base::debug::ConvertableToTraceFormat>(); +} + void TracedPicture::AppendAsTraceFormat(std::string* out) const { + if (is_alias_) + AppendPictureAlias(out); + else + AppendPicture(out); +} + +void TracedPicture::AppendPictureAlias(std::string* out) const { + scoped_ptr<base::DictionaryValue> alias(new base::DictionaryValue()); + alias->SetString("id_ref", base::StringPrintf("%p", picture_.get())); + + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->Set("alias", alias.release()); + + std::string tmp; + base::JSONWriter::Write(res.get(), &tmp); + out->append(tmp); +} + +void TracedPicture::AppendPicture(std::string* out) const { scoped_ptr<base::Value> value = picture_->AsValue(); std::string tmp; base::JSONWriter::Write(value.get(), &tmp); diff --git a/chromium/cc/debug/traced_picture.h b/chromium/cc/debug/traced_picture.h index 9137d8f830e..50511f2034a 100644 --- a/chromium/cc/debug/traced_picture.h +++ b/chromium/cc/debug/traced_picture.h @@ -22,10 +22,17 @@ class TracedPicture : public base::debug::ConvertableToTraceFormat { static scoped_ptr<base::debug::ConvertableToTraceFormat> AsTraceablePicture(Picture* picture); + static scoped_ptr<base::debug::ConvertableToTraceFormat> + AsTraceablePictureAlias(Picture* original); + virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE; private: + void AppendPicture(std::string* out) const; + void AppendPictureAlias(std::string* out) const; + scoped_refptr<Picture> picture_; + bool is_alias_; DISALLOW_COPY_AND_ASSIGN(TracedPicture); }; |