aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/webrender/debugger/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrender/debugger/src')
-rw-r--r--third_party/webrender/debugger/src/App.vue55
-rw-r--r--third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue37
-rw-r--r--third_party/webrender/debugger/src/components/DocumentViewPage.vue37
-rw-r--r--third_party/webrender/debugger/src/components/NavBar.vue41
-rw-r--r--third_party/webrender/debugger/src/components/NavMenu.vue33
-rw-r--r--third_party/webrender/debugger/src/components/OptionsPage.vue162
-rw-r--r--third_party/webrender/debugger/src/components/PassViewPage.vue37
-rw-r--r--third_party/webrender/debugger/src/components/RenderTaskViewPage.vue37
-rw-r--r--third_party/webrender/debugger/src/components/ScreenshotPage.vue32
-rw-r--r--third_party/webrender/debugger/src/components/TreeView.vue40
-rw-r--r--third_party/webrender/debugger/src/main.js14
-rw-r--r--third_party/webrender/debugger/src/store/index.js105
12 files changed, 630 insertions, 0 deletions
diff --git a/third_party/webrender/debugger/src/App.vue b/third_party/webrender/debugger/src/App.vue
new file mode 100644
index 00000000000..01d303e79e5
--- /dev/null
+++ b/third_party/webrender/debugger/src/App.vue
@@ -0,0 +1,55 @@
+<template>
+ <div>
+ <app-navbar></app-navbar>
+ <div class="section">
+ <div class="container">
+ <div class="columns">
+ <div class="column is-3">
+ <app-navmenu></app-navmenu>
+ </div>
+ <div class="column">
+ <app-options v-if="page == 'options'"></app-options>
+ <app-passview v-if="page == 'passes'"></app-passview>
+ <app-rendertaskview v-if="page == 'render_tasks'"></app-rendertaskview>
+ <app-documentview v-if="page == 'documents'"></app-documentview>
+ <app-clipscrolltreeview v-if="page == 'clip_scroll_tree'"></app-clipscrolltreeview>
+ <app-screenshotview v-if="page == 'screenshot'"></app-screenshotview>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import NavBar from './components/NavBar.vue'
+import NavMenu from './components/NavMenu.vue'
+import OptionsPage from './components/OptionsPage.vue'
+import PassViewPage from './components/PassViewPage.vue'
+import RenderTaskViewPage from './components/RenderTaskViewPage.vue'
+import DocumentViewPage from './components/DocumentViewPage.vue'
+import ClipScrollTreeViewPage from './components/ClipScrollTreeViewPage.vue'
+import ScreenshotPage from './components/ScreenshotPage.vue'
+
+export default {
+ name: 'app',
+ components: {
+ 'app-navbar': NavBar,
+ 'app-navmenu': NavMenu,
+ 'app-options': OptionsPage,
+ 'app-passview': PassViewPage,
+ 'app-rendertaskview': RenderTaskViewPage,
+ 'app-documentview': DocumentViewPage,
+ 'app-clipscrolltreeview': ClipScrollTreeViewPage,
+ 'app-screenshotview': ScreenshotPage,
+ },
+ computed: {
+ page() {
+ return this.$store.state.page;
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue b/third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
new file mode 100644
index 00000000000..66a1edaf304
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
@@ -0,0 +1,37 @@
+<template>
+ <div class="box">
+ <h1 class="title">Clip-Scroll Tree <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
+ <hr/>
+ <div>
+ <ul>
+ <app-treeview :model=clip_scroll_tree></app-treeview>
+ </ul>
+ </div>
+ </div>
+</template>
+
+<script>
+import TreeView from './TreeView.vue'
+
+export default {
+ components: {
+ 'app-treeview': TreeView,
+ },
+ methods: {
+ fetch: function() {
+ this.$store.dispatch('sendMessage', "fetch_clip_scroll_tree");
+ }
+ },
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ },
+ clip_scroll_tree() {
+ return this.$store.state.clip_scroll_tree
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/DocumentViewPage.vue b/third_party/webrender/debugger/src/components/DocumentViewPage.vue
new file mode 100644
index 00000000000..6d5f02da735
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/DocumentViewPage.vue
@@ -0,0 +1,37 @@
+<template>
+ <div class="box">
+ <h1 class="title">Documents <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
+ <hr/>
+ <div>
+ <ul>
+ <app-treeview :model=documents></app-treeview>
+ </ul>
+ </div>
+ </div>
+</template>
+
+<script>
+import TreeView from './TreeView.vue'
+
+export default {
+ components: {
+ 'app-treeview': TreeView,
+ },
+ methods: {
+ fetch: function() {
+ this.$store.dispatch('sendMessage', "fetch_documents");
+ }
+ },
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ },
+ documents() {
+ return this.$store.state.documents
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/NavBar.vue b/third_party/webrender/debugger/src/components/NavBar.vue
new file mode 100644
index 00000000000..2f8008d67d4
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/NavBar.vue
@@ -0,0 +1,41 @@
+<template>
+ <nav class="navbar has-shadow">
+ <div class="navbar-brand">
+ <a class="navbar-item" href="#">WebRender Debugger</a>
+ </div>
+
+ <div class="navbar-menu">
+ <div class="navbar-start"></div>
+
+ <div class="navbar-end">
+ <div class="navbar-item">
+ <p class="control">
+ <button v-if="isConnected" @click="disconnect" class="button is-danger">Disconnect</button>
+ <button v-else @click="connect" class="button is-success">Connect</button>
+ </p>
+ </div>
+ </div>
+ </div>
+ </nav>
+</template>
+
+<script>
+export default {
+ computed: {
+ isConnected() {
+ return this.$store.state.connected;
+ },
+ },
+ methods: {
+ connect() {
+ this.$store.dispatch('connect');
+ },
+ disconnect() {
+ this.$store.dispatch('disconnect');
+ },
+ }
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/NavMenu.vue b/third_party/webrender/debugger/src/components/NavMenu.vue
new file mode 100644
index 00000000000..5a7cc3512a4
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/NavMenu.vue
@@ -0,0 +1,33 @@
+<template>
+ <aside class="menu">
+ <p class="menu-label">
+ Pages
+ </p>
+ <ul class="menu-list">
+ <li><a @click="setPage('options')" :class="{ 'is-active': page == 'options' }">Debug Options</a></li>
+ <li><a @click="setPage('passes')" :class="{ 'is-active': page == 'passes' }">Passes</a></li>
+ <li><a @click="setPage('render_tasks')" :class="{ 'is-active': page == 'render_tasks' }">Render Tasks</a></li>
+ <li><a @click="setPage('documents')" :class="{ 'is-active': page == 'documents' }">Documents</a></li>
+ <li><a @click="setPage('clip_scroll_tree')" v-bind:class="{ 'is-active': page == 'clip_scroll_tree' }">Clip-Scroll Tree</a></li>
+ <li><a @click="setPage('screenshot')" v-bind:class="{ 'is-active': page == 'screenshot' }">Screenshot</a></li>
+ </ul>
+ </aside>
+</template>
+
+<script>
+export default {
+ methods: {
+ setPage(name) {
+ this.$store.commit('setPage', name);
+ },
+ },
+ computed: {
+ page() {
+ return this.$store.state.page;
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/OptionsPage.vue b/third_party/webrender/debugger/src/components/OptionsPage.vue
new file mode 100644
index 00000000000..fd8288c42cc
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/OptionsPage.vue
@@ -0,0 +1,162 @@
+<template>
+ <div class="box">
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setProfiler($event.target.checked)">
+ Profiler
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setTextureCacheDebugger($event.target.checked)">
+ Texture cache debugger
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setRenderTargetDebugger($event.target.checked)">
+ Render target debugger
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setAlphaRectsDebugger($event.target.checked)">
+ Alpha primitive rects debugger
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setGpuTimeQueries($event.target.checked)">
+ Enable GPU time queries
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setGpuSampleQueries($event.target.checked)">
+ Enable GPU sample queries
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setOpaquePass(!$event.target.checked)">
+ Disable opaque pass
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setAlphaPass(!$event.target.checked)">
+ Disable alpha pass
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setClipMasks(!$event.target.checked)">
+ Disable clip masks
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setTextPrims(!$event.target.checked)">
+ Disable text primitives
+ </label>
+ </div>
+ <div class="field">
+ <label class="checkbox">
+ <input type="checkbox" :disabled="disabled" v-on:click="setGradientPrims(!$event.target.checked)">
+ Disable gradient primitives
+ </label>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ }
+ },
+ methods: {
+ setProfiler(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_profiler");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_profiler");
+ }
+ },
+ setTextureCacheDebugger(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_texture_cache_debug");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_texture_cache_debug");
+ }
+ },
+ setRenderTargetDebugger(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_render_target_debug");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_render_target_debug");
+ }
+ },
+ setAlphaRectsDebugger(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_alpha_rects_debug");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_alpha_rects_debug");
+ }
+ },
+ setGpuTimeQueries(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_gpu_time_queries");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_gpu_time_queries");
+ }
+ },
+ setGpuSampleQueries(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_gpu_sample_queries");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_gpu_sample_queries");
+ }
+ },
+ setOpaquePass(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_opaque_pass");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_opaque_pass");
+ }
+ },
+ setAlphaPass(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_alpha_pass");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_alpha_pass");
+ }
+ },
+ setClipMasks(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_clip_masks");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_clip_masks");
+ }
+ },
+ setTextPrims(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_text_prims");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_text_prims");
+ }
+ },
+ setGradientPrims(enabled) {
+ if (enabled) {
+ this.$store.dispatch('sendMessage', "enable_gradient_prims");
+ } else {
+ this.$store.dispatch('sendMessage', "disable_gradient_prims");
+ }
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/PassViewPage.vue b/third_party/webrender/debugger/src/components/PassViewPage.vue
new file mode 100644
index 00000000000..0ab6d7c4464
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/PassViewPage.vue
@@ -0,0 +1,37 @@
+<template>
+ <div class="box">
+ <h1 class="title">Passes <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
+ <hr/>
+ <div v-for="(pass, pass_index) in passes">
+ <p class="has-text-black-bis">Pass {{pass_index}}</p>
+ <div v-for="(target, target_index) in pass.targets">
+ <p style="text-indent: 2em;" class="has-text-grey-dark">Target {{target_index}} ({{target.kind}})</p>
+ <div v-for="(batch, batch_index) in target.batches">
+ <p style="text-indent: 4em;" class="has-text-grey">Batch {{batch_index}} ({{batch.description}}, {{batch.kind}}, {{batch.count}} instances)</p>
+ </div>
+ </div>
+ <hr/>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ methods: {
+ fetch: function() {
+ this.$store.dispatch('sendMessage', "fetch_passes");
+ }
+ },
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ },
+ passes() {
+ return this.$store.state.passes
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/RenderTaskViewPage.vue b/third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
new file mode 100644
index 00000000000..c3937fe0ce2
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
@@ -0,0 +1,37 @@
+<template>
+ <div class="box">
+ <h1 class="title">Render Tasks <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
+ <hr/>
+ <div>
+ <ul>
+ <app-treeview :model=render_tasks></app-treeview>
+ </ul>
+ </div>
+ </div>
+</template>
+
+<script>
+import TreeView from './TreeView.vue'
+
+export default {
+ components: {
+ 'app-treeview': TreeView,
+ },
+ methods: {
+ fetch: function() {
+ this.$store.dispatch('sendMessage', "fetch_render_tasks");
+ }
+ },
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ },
+ render_tasks() {
+ return this.$store.state.render_tasks
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/ScreenshotPage.vue b/third_party/webrender/debugger/src/components/ScreenshotPage.vue
new file mode 100644
index 00000000000..8d4017856e4
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/ScreenshotPage.vue
@@ -0,0 +1,32 @@
+<template>
+ <div class="box">
+ <h1 class="title">Screenshot <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
+ <hr/>
+ <div>
+ <ul>
+ <img v-if="screenshot.length > 0" style="transform: scaleY(-1); width: 1024px; height:768px" :src="'data:image/png;base64,' + screenshot" />
+ </ul>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ computed: {
+ disabled() {
+ return !this.$store.state.connected
+ },
+ screenshot() {
+ return this.$store.state.screenshot
+ },
+ },
+ methods: {
+ fetch: function() {
+ this.$store.dispatch('sendMessage', "fetch_screenshot");
+ }
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/components/TreeView.vue b/third_party/webrender/debugger/src/components/TreeView.vue
new file mode 100644
index 00000000000..bde473bda2f
--- /dev/null
+++ b/third_party/webrender/debugger/src/components/TreeView.vue
@@ -0,0 +1,40 @@
+<template>
+ <li>
+ <div v-on:click="toggle">
+ <span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
+ {{model.description}}
+ </div>
+ <ul style="padding-left: 1em; line-height: 1.5em;" v-show="open" v-if="isFolder">
+ <treeview v-for="model in model.children" :model="model"></treeview>
+ </ul>
+ </li>
+</template>
+
+<script>
+export default {
+ name: 'treeview',
+ props: [
+ 'model',
+ ],
+ data: function () {
+ return {
+ open: false
+ }
+ },
+ computed: {
+ isFolder: function () {
+ return this.model.children && this.model.children.length
+ }
+ },
+ methods: {
+ toggle: function () {
+ if (this.isFolder) {
+ this.open = !this.open
+ }
+ },
+ },
+}
+</script>
+
+<style>
+</style>
diff --git a/third_party/webrender/debugger/src/main.js b/third_party/webrender/debugger/src/main.js
new file mode 100644
index 00000000000..1259c32a0f3
--- /dev/null
+++ b/third_party/webrender/debugger/src/main.js
@@ -0,0 +1,14 @@
+import Vue from 'vue';
+import Buefy from 'buefy';
+import 'buefy/dist/buefy.css';
+import "vue-material-design-icons/styles.css";
+import App from './App.vue';
+import store from './store';
+
+Vue.use(Buefy);
+
+new Vue({
+ el: '#app',
+ store,
+ render: h => h(App)
+})
diff --git a/third_party/webrender/debugger/src/store/index.js b/third_party/webrender/debugger/src/store/index.js
new file mode 100644
index 00000000000..7749d7a8416
--- /dev/null
+++ b/third_party/webrender/debugger/src/store/index.js
@@ -0,0 +1,105 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+class Connection {
+ constructor() {
+ this.ws = null;
+ }
+
+ connect(context) {
+ var ws = new WebSocket("ws://127.0.0.1:3583");
+
+ ws.onopen = function() {
+ context.commit('setConnected', true);
+ }
+
+ ws.onmessage = function(evt) {
+ var json = JSON.parse(evt.data);
+ if (json['kind'] == "passes") {
+ context.commit('setPasses', json['passes']);
+ } else if (json['kind'] == "render_tasks") {
+ context.commit('setRenderTasks', json['root']);
+ } else if (json['kind'] == "documents") {
+ context.commit('setDocuments', json['root']);
+ } else if (json['kind'] == "clip_scroll_tree") {
+ context.commit('setClipScrollTree', json['root']);
+ } else if (json['kind'] == "screenshot") {
+ context.commit('setScreenshot', json['data']);
+ } else {
+ console.warn("unknown message kind: " + json['kind']);
+ }
+ }
+
+ ws.onclose = function() {
+ context.commit('setConnected', false);
+ }
+
+ this.ws = ws;
+ }
+
+ send(msg) {
+ if (this.ws !== null) {
+ this.ws.send(msg);
+ }
+ }
+
+ disconnect() {
+ if (this.ws !== null) {
+ this.ws.close();
+ this.ws = null;
+ }
+ }
+}
+
+var connection = new Connection();
+
+const store = new Vuex.Store({
+ strict: true,
+ state: {
+ connected: false,
+ page: 'options',
+ passes: [],
+ render_tasks: [],
+ documents: [],
+ clip_scroll_tree: [],
+ screenshot: [],
+ },
+ mutations: {
+ setConnected(state, connected) {
+ state.connected = connected;
+ },
+ setPage(state, name) {
+ state.page = name;
+ },
+ setPasses(state, passes) {
+ state.passes = passes;
+ },
+ setRenderTasks(state, render_tasks) {
+ state.render_tasks = render_tasks;
+ },
+ setDocuments(state, documents) {
+ state.documents = documents;
+ },
+ setClipScrollTree(state, clip_scroll_tree) {
+ state.clip_scroll_tree = clip_scroll_tree;
+ },
+ setScreenshot(state, screenshot) {
+ state.screenshot = screenshot;
+ },
+ },
+ actions: {
+ connect(context) {
+ connection.connect(context);
+ },
+ disconnect(context) {
+ connection.disconnect();
+ },
+ sendMessage(context, msg) {
+ connection.send(msg);
+ }
+ }
+});
+
+export default store;