summaryrefslogtreecommitdiff
path: root/chromium/cc/debug
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2013-12-11 21:33:03 +0100
committerAndras Becsi <andras.becsi@digia.com>2013-12-13 12:34:07 +0100
commitf2a33ff9cbc6d19943f1c7fbddd1f23d23975577 (patch)
tree0586a32aa390ade8557dfd6b4897f43a07449578 /chromium/cc/debug
parent5362912cdb5eea702b68ebe23702468d17c3017a (diff)
downloadqtwebengine-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.h17
-rw-r--r--chromium/cc/debug/fake_web_graphics_context_3d.h3
-rw-r--r--chromium/cc/debug/frame_rate_counter.cc24
-rw-r--r--chromium/cc/debug/frame_rate_counter.h2
-rw-r--r--chromium/cc/debug/overdraw_metrics.cc14
-rw-r--r--chromium/cc/debug/rendering_stats.cc233
-rw-r--r--chromium/cc/debug/rendering_stats.h106
-rw-r--r--chromium/cc/debug/rendering_stats_instrumentation.cc85
-rw-r--r--chromium/cc/debug/rendering_stats_instrumentation.h35
-rw-r--r--chromium/cc/debug/test_context_provider.cc240
-rw-r--r--chromium/cc/debug/test_context_provider.h90
-rw-r--r--chromium/cc/debug/test_web_graphics_context_3d.cc632
-rw-r--r--chromium/cc/debug/test_web_graphics_context_3d.h292
-rw-r--r--chromium/cc/debug/traced_picture.cc30
-rw-r--r--chromium/cc/debug/traced_picture.h7
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);
};