Merge graphics branch to m-c a=merge

MozReview-Commit-ID: 3R6vECA8sI1
This commit is contained in:
Wes Kocher 2017-03-13 13:09:58 -07:00
Родитель a5c2b27889 916f12ed8f
Коммит 15777c0256
215 изменённых файлов: 11270 добавлений и 18463 удалений

Просмотреть файл

@ -49,14 +49,14 @@ skip-if(Android)
skip-if(Android) == webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=1&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) == webgl-color-test.html?frame=1&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
@ -66,14 +66,14 @@ skip-if(Android)
skip-if(Android) == webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) fails-if(webrender) == webgl-color-test.html?frame=6&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
@ -83,14 +83,14 @@ skip-if(Android)
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
@ -100,14 +100,14 @@ skip-if(Android)
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) skip-if(Android) pref(webgl.force-layers-readback,true) fails-if(webrender) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
# Check for hanging bindings/state settings:
skip-if(Android) == webgl-hanging-fb-test.html?__&________ wrapper.html?green.png
@ -157,7 +157,7 @@ skip-if(!winWidget) pref(webgl.disable-angle,true) == webgl-color-test.html?nat
== stroketext-shadow.html stroketext-shadow-ref.html
# focus rings
pref(canvas.focusring.enabled,true) skip-if(cocoaWidget) skip-if(winWidget) needs-focus fails-if(webrender) == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
pref(canvas.focusring.enabled,true) skip-if(cocoaWidget) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
pref(canvas.customfocusring.enabled,true) skip-if(Android||cocoaWidget||winWidget) fuzzy-if(gtkWidget,64,410) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
# Check that captureStream() displays in a local video element

Просмотреть файл

@ -62,4 +62,4 @@ pref(permissions.default.image,1) HTTP == bug1196784-with-srcset.html bug1196784
pref(permissions.default.image,2) HTTP == bug1196784-with-srcset.html bug1196784-no-srcset.html
# Test video with rotation information can be rotated.
fails-if(webrender) == bug1228601-video-rotation-90.html bug1228601-video-rotated-ref.html
== bug1228601-video-rotation-90.html bug1228601-video-rotated-ref.html

Просмотреть файл

@ -1,25 +1,25 @@
# basic sanity checking
random-if(!haveTestPlugin) != plugin-sanity.html about:blank
fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) fails-if(webrender) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,164000) fails-if(webrender) == plugin-alpha-opacity.html div-alpha-opacity.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html # bug 631832
# fuzzy because of anti-aliasing in dashed border
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fails-if(webrender) == border-padding-1.html border-padding-1-ref.html # bug 629430
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html # bug 629430
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html # bug 629430
skip-if(!webrender) pref(layers.advanced.border-layers,true) fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(!haveTestPlugin||Android) fails-if(webrender) == border-padding-3.html border-padding-3-ref.html # bug 629430 # bug 773482
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(!haveTestPlugin||Android) == border-padding-3.html border-padding-3-ref.html # bug 629430 # bug 773482
# The following two "pluginproblemui-direction" tests are unreliable on all platforms. They should be re-written or replaced.
#random-if(cocoaWidget||d2d||/^Windows\x20NT\x205\.1/.test(http.oscpu)) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html # bug 567367
#random-if(cocoaWidget) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-2.html pluginproblemui-direction-2-ref.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) fails-if(webrender) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) fails-if(webrender) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) fails-if(webrender) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) fails-if(webrender) == plugin-background.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) fails-if(webrender) == plugin-background-1-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) fails-if(webrender) == plugin-background-2-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) fails-if(webrender) == plugin-background-5-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) fails-if(webrender) == plugin-background-10-step.html plugin-background-ref.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-1-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-2-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-5-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-10-step.html plugin-background-ref.html
random-if(!haveTestPlugin) == plugin-transform-1.html plugin-transform-1-ref.html
fails-if(!haveTestPlugin) == plugin-transform-2.html plugin-transform-2-ref.html
skip-if(!haveTestPlugin) == shrink-1.html shrink-1-ref.html

Просмотреть файл

@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
Latest Commit: 501e3d79c8a3019762bd8bd2d00eecf7811a84de
Latest Commit: e30fb2914928c0e596d8632ed234647c0fd1492e

Просмотреть файл

@ -69,10 +69,12 @@ enum class TextureFlags : uint32_t {
// This flag is only used in the parent process.
INVALID_COMPOSITOR = 1 << 12,
// The texture was created by converting from YCBCR to RGB
RGB_FROM_YCBCR = 1 << 13,
RGB_FROM_YCBCR = 1 << 13,
// The texture is used for snapshot.
SNAPSHOT = 1 << 14,
// OR union of all valid bits
ALL_BITS = (1 << 14) - 1,
ALL_BITS = (1 << 15) - 1,
// the default flags
DEFAULT = NO_FLAGS
};

Просмотреть файл

@ -17,6 +17,7 @@ namespace layers {
already_AddRefed<TextureHost>
CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
#ifdef XP_MACOSX
@ -26,7 +27,7 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
return MakeAndAddRef<MacIOSurfaceTextureHostBasic>(aFlags, desc);
}
#endif
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
}
} // namespace layers

Просмотреть файл

@ -43,6 +43,7 @@ class Compositor;
class ThebesBufferData;
class TiledContentHost;
class CompositableParentManager;
class WebRenderImageHost;
struct EffectChain;
struct ImageCompositeNotificationInfo {
@ -148,6 +149,7 @@ public:
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
virtual WebRenderImageHost* AsWebRenderImageHost() { return nullptr; }
typedef uint32_t AttachFlags;
static const AttachFlags NO_FLAGS = 0;

Просмотреть файл

@ -9,6 +9,7 @@
#include "LayerScope.h"
#include "LayersLogging.h" // for AppendToString
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/Shmem.h" // for Shmem
#include "mozilla/layers/CompositableTransactionParent.h" // for CompositableParentManager
#include "mozilla/layers/CompositorBridgeParent.h"
@ -20,6 +21,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/GPUVideoTextureHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "nsAString.h"
#include "mozilla/RefPtr.h" // for nsRefPtr
#include "nsPrintfCString.h" // for nsPrintfCString
@ -160,18 +162,21 @@ TextureHost::SetLastFwdTransactionId(uint64_t aTransactionId)
// implemented in TextureHostOGL.cpp
already_AddRefed<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
// implemented in TextureHostBasic.cpp
already_AddRefed<TextureHost> CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
// implemented in TextureD3D11.cpp
already_AddRefed<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
already_AddRefed<TextureHost>
TextureHost::Create(const SurfaceDescriptor& aDesc,
@ -184,19 +189,19 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TSurfaceDescriptorDIB:
case SurfaceDescriptor::TSurfaceDescriptorFileMapping:
case SurfaceDescriptor::TSurfaceDescriptorGPUVideo:
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (aBackend == LayersBackend::LAYERS_OPENGL ||
aBackend == LayersBackend::LAYERS_WR) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
} else {
return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
return CreateTextureHostBasic(aDesc, aDeallocator, aBackend, aFlags);
}
#ifdef MOZ_X11
@ -209,16 +214,28 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
#ifdef XP_WIN
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags);
return CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
#endif
default:
MOZ_CRASH("GFX: Unsupported Surface type host");
}
}
bool WrapWithWebRenderTextureHost(LayersBackend aBackend,
TextureFlags aFlags)
{
if (!gfxVars::UseWebRender() ||
(aFlags & TextureFlags::SNAPSHOT) ||
(aBackend != LayersBackend::LAYERS_WR)) {
return false;
}
return true;
}
already_AddRefed<TextureHost>
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
@ -232,12 +249,18 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
bufferDesc.desc(),
aDeallocator,
aFlags);
if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
result = new WebRenderTextureHost(aFlags, result);
}
break;
}
case MemoryOrShmem::Tuintptr_t: {
result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(data.get_uintptr_t()),
bufferDesc.desc(),
aFlags);
if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
result = new WebRenderTextureHost(aFlags, result);
}
break;
}
default:

Просмотреть файл

@ -54,6 +54,7 @@ class TextureSourceBasic;
class DataTextureSource;
class PTextureParent;
class TextureParent;
class WebRenderTextureHost;
class WrappingTextureSourceYCbCrBasic;
/**
@ -584,6 +585,8 @@ public:
virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
protected:
void ReadUnlock();
@ -880,6 +883,7 @@ private:
already_AddRefed<TextureHost>
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
} // namespace layers

Просмотреть файл

@ -633,12 +633,13 @@ DXGIYCbCrTextureData::Deallocate(LayersIPCChannel*)
already_AddRefed<TextureHost>
CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
break;
}
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {

Просмотреть файл

@ -1130,7 +1130,10 @@ CompositorBridgeChild::HandleFatalError(const char* aName, const char* aMsg) con
}
PWebRenderBridgeChild*
CompositorBridgeChild::AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, TextureFactoryIdentifier*, uint32_t *aIdNamespace)
CompositorBridgeChild::AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize&,
TextureFactoryIdentifier*,
uint32_t *aIdNamespace)
{
WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
child->AddIPDLReference();

Просмотреть файл

@ -223,7 +223,9 @@ public:
void WillEndTransaction();
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, TextureFactoryIdentifier*,
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize&,
TextureFactoryIdentifier*,
uint32_t*) override;
bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;

Просмотреть файл

@ -1575,6 +1575,7 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
PWebRenderBridgeParent*
CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint32_t* aIdNamespace)
{
@ -1591,7 +1592,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
MOZ_ASSERT(mWidget);
RefPtr<widget::CompositorWidget> widget = mWidget;
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget));
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(
gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget), aSize);
RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
MOZ_ASSERT(api); // TODO have a fallback
api->SetRootPipeline(aPipelineId);

Просмотреть файл

@ -455,6 +455,7 @@ public:
}
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint32_t* aIdNamespace) override;
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;

Просмотреть файл

@ -199,6 +199,7 @@ CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
PWebRenderBridgeParent*
CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint32_t *aIdNamespace)
{
@ -222,7 +223,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
WebRenderBridgeParent* parent = nullptr;
RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder();
RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
parent->AddRef(); // IPDL reference

Просмотреть файл

@ -155,6 +155,7 @@ public:
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override;
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint32_t* aIdNamespace) override;
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;

Просмотреть файл

@ -97,6 +97,8 @@ public:
virtual bool UsesImageBridge() const { return false; }
virtual bool UsesWebRenderBridge() const { return false; }
protected:
void Finalize() {}

Просмотреть файл

@ -30,6 +30,7 @@ using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasi
using mozilla::CSSIntRegion from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDeviceIntRegion from "Units.h";
using mozilla::LayoutDeviceIntSize from "Units.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUniformityData.h";
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
@ -242,7 +243,7 @@ parent:
sync SyncWithCompositor();
// The pipelineId is the same as the layersId
sync PWebRenderBridge(PipelineId pipelineId)
sync PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize)
returns (TextureFactoryIdentifier textureFactoryIdentifier, uint32_t idNamespace); //XXX: use the WrIdNamespace type
child:

Просмотреть файл

@ -12,7 +12,7 @@ include protocol PTexture;
using WrBorderRadius from "mozilla/webrender/webrender_ffi.h";
using WrBorderSide from "mozilla/webrender/webrender_ffi.h";
using WrColor from "mozilla/webrender/webrender_ffi.h";
using WrLayoutSize from "mozilla/webrender/webrender_ffi.h";
using WrSize from "mozilla/webrender/webrender_ffi.h";
using WrRect from "mozilla/webrender/webrender_ffi.h";
using WrPoint from "mozilla/webrender/webrender_ffi.h";
using WrGradientStop from "mozilla/webrender/webrender_ffi.h";
@ -32,118 +32,11 @@ using mozilla::LayerIntRegion from "Units.h";
namespace mozilla {
namespace layers {
struct OpDPPushStackingContext {
WrRect bounds;
WrRect overflow;
MaybeImageMask mask;
float opacity;
Animation[] animations;
Matrix4x4 matrix;
WrMixBlendMode mixBlendMode;
uint64_t scrollid;
};
struct OpDPPopStackingContext { };
struct OpDPPushScrollLayer {
WrRect bounds;
WrRect overflow;
MaybeImageMask mask;
uint64_t scrollid;
};
struct OpDPPopScrollLayer { };
struct OpDPPushRect {
WrRect bounds;
WrRect clip;
WrColor color;
};
struct OpDPPushBorder {
WrRect bounds;
WrRect clip;
WrBorderSide top;
WrBorderSide right;
WrBorderSide bottom;
WrBorderSide left;
WrBorderRadius radius;
};
struct OpDPPushLinearGradient {
WrRect bounds;
WrRect clip;
WrPoint startPoint;
WrPoint endPoint;
WrGradientExtendMode extendMode;
WrGradientStop[] stops;
};
struct OpDPPushRadialGradient {
WrRect bounds;
WrRect clip;
WrPoint startCenter;
WrPoint endCenter;
float startRadius;
float endRadius;
WrGradientExtendMode extendMode;
WrGradientStop[] stops;
};
struct OpDPPushImage {
WrRect bounds;
WrRect clip;
MaybeImageMask mask;
ImageRendering filter;
ImageKey key;
};
struct OpAddExternalImage {
uint64_t externalImageId;
ImageKey key;
};
struct OpDPPushIframe {
WrRect bounds;
WrRect clip;
PipelineId pipelineId;
};
struct OpDPPushText {
WrRect bounds;
WrRect clip;
WrGlyphArray[] glyph_array;
float glyph_size;
FontKey key;
};
struct OpDPPushBoxShadow {
WrRect rect;
WrRect clip;
WrRect box_bounds;
WrPoint offset;
WrColor color;
float blur_radius;
float spread_radius;
float border_radius;
WrBoxShadowClipMode clip_mode;
};
union WebRenderCommand {
OpDPPushStackingContext;
OpDPPopStackingContext;
OpDPPushScrollLayer;
OpDPPopScrollLayer;
OpDPPushRect;
OpDPPushBorder;
OpDPPushLinearGradient;
OpDPPushRadialGradient;
OpDPPushImage;
OpDPPushIframe;
OpDPPushText;
OpDPPushBoxShadow;
};
union WebRenderParentCommand {
OpAddExternalImage;
CompositableOperation;

Просмотреть файл

@ -191,6 +191,7 @@ EXPORTS.mozilla.layers += [
'SourceSurfaceVolatileData.h',
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'wr/WebRenderBorderLayer.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCompositableHolder.h',
@ -199,6 +200,7 @@ EXPORTS.mozilla.layers += [
'wr/WebRenderLayerManager.h',
'wr/WebRenderLayersLogging.h',
'wr/WebRenderMessageUtils.h',
'wr/WebRenderTextureHost.h',
]
if CONFIG['MOZ_X11']:
@ -389,6 +391,7 @@ UNIFIED_SOURCES += [
'wr/WebRenderLayersLogging.cpp',
'wr/WebRenderPaintedLayer.cpp',
'wr/WebRenderTextLayer.cpp',
'wr/WebRenderTextureHost.cpp',
]
SOURCES += [

Просмотреть файл

@ -40,13 +40,16 @@ class Compositor;
already_AddRefed<TextureHost>
CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
result = CreateBackendIndependentTextureHost(aDesc,
aDeallocator, aFlags);
aDeallocator,
aBackend,
aFlags);
break;
}

Просмотреть файл

@ -17,60 +17,62 @@ namespace layers {
using namespace mozilla::gfx;
void
WebRenderBorderLayer::RenderLayer()
/* static */void
WebRenderBorderLayer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
Rect aRect,
Rect aClipRect,
Rect aRelBounds,
Rect aOverflow)
{
WrScrollFrameStackingContextGenerator scrollFrames(this);
aBuilder.PushStackingContext(wr::ToWrRect(aRelBounds),
wr::ToWrRect(aOverflow),
nullptr,
1.0f,
aLayer->GetLayer()->GetTransform(),
wr::MixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(aRect), aBuilder.BuildClipRegion(wr::ToWrRect(aClipRect)),
wr::ToWrBorderWidths(aWidths[0], aWidths[1], aWidths[2], aWidths[3]),
wr::ToWrBorderSide(aColors[0], aBorderStyles[0]),
wr::ToWrBorderSide(aColors[1], aBorderStyles[1]),
wr::ToWrBorderSide(aColors[2], aBorderStyles[2]),
wr::ToWrBorderSide(aColors[3], aBorderStyles[3]),
wr::ToWrBorderRadius(aCorners[eCornerTopLeft], aCorners[eCornerTopRight],
aCorners[eCornerBottomLeft], aCorners[eCornerBottomRight]));
aBuilder.PopStackingContext();
}
LayerIntRect bounds = GetVisibleRegion().GetBounds();
Rect rect(0, 0, bounds.width, bounds.height);
Rect clip;
Matrix4x4 transform = GetTransform();
if (GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(IntRectToRect(GetClipRect().ref().ToUnknownRect())));
} else {
clip = rect;
}
void
WebRenderBorderLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
gfx::Rect rect = GetWrBoundsRect();
gfx::Rect clipRect = GetWrClipRect(rect);
Rect overflow(0, 0, relBounds.width, relBounds.height);
DumpLayerInfo("BorderLayer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("BorderLayer %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(rect).c_str(),
Stringify(clip).c_str());
}
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
Nothing(),
1.0f,
GetAnimations(),
transform,
WrMixBlendMode::Normal,
FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand(
OpDPPushBorder(wr::ToWrRect(rect), wr::ToWrRect(clip),
wr::ToWrBorderSide(mWidths[0], mColors[0], mBorderStyles[0]),
wr::ToWrBorderSide(mWidths[1], mColors[1], mBorderStyles[1]),
wr::ToWrBorderSide(mWidths[2], mColors[2], mBorderStyles[2]),
wr::ToWrBorderSide(mWidths[3], mColors[3], mBorderStyles[3]),
wr::ToWrBorderRadius(mCorners[0], mCorners[1], mCorners[3], mCorners[2])));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
nullptr,
1.0f,
//GetAnimations(),
GetTransform(),
wr::MixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(rect), aBuilder.BuildClipRegion(wr::ToWrRect(clipRect)),
wr::ToWrBorderWidths(mWidths[0], mWidths[1], mWidths[2], mWidths[3]),
wr::ToWrBorderSide(mColors[0], mBorderStyles[0]),
wr::ToWrBorderSide(mColors[1], mBorderStyles[1]),
wr::ToWrBorderSide(mColors[2], mBorderStyles[2]),
wr::ToWrBorderSide(mColors[3], mBorderStyles[3]),
wr::ToWrBorderRadius(mCorners[eCornerTopLeft], mCorners[eCornerTopRight],
mCorners[eCornerBottomLeft], mCorners[eCornerBottomRight]));
aBuilder.PopStackingContext();
}
} // namespace layers

Просмотреть файл

@ -21,6 +21,18 @@ public:
MOZ_COUNT_CTOR(WebRenderBorderLayer);
}
static void
CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
gfx::Rect aRect,
gfx::Rect aClipRect,
gfx::Rect aRelBounds,
gfx::Rect aOverflow);
protected:
virtual ~WebRenderBorderLayer()
{
@ -29,7 +41,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
};
} // namespace layers

Просмотреть файл

@ -46,20 +46,6 @@ WebRenderBridgeChild::ActorDestroy(ActorDestroyReason why)
mDestroyed = true;
}
void
WebRenderBridgeChild::AddWebRenderCommand(const WebRenderCommand& aCmd)
{
MOZ_ASSERT(mIsInTransaction);
mCommands.AppendElement(aCmd);
}
void
WebRenderBridgeChild::AddWebRenderCommands(const nsTArray<WebRenderCommand>& aCommands)
{
MOZ_ASSERT(mIsInTransaction);
mCommands.AppendElements(aCommands);
}
void
WebRenderBridgeChild::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd)
{
@ -88,114 +74,8 @@ WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
return true;
}
wr::BuiltDisplayList
WebRenderBridgeChild::ProcessWebrenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderCommand>& aCommands)
{
wr::DisplayListBuilder builder(mPipelineId);
builder.Begin(ViewAs<LayerPixel>(aSize));
for (InfallibleTArray<WebRenderCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
const WebRenderCommand& cmd = aCommands[i];
switch (cmd.type()) {
case WebRenderCommand::TOpDPPushStackingContext: {
const OpDPPushStackingContext& op = cmd.get_OpDPPushStackingContext();
builder.PushStackingContext(op.bounds(), op.overflow(), op.mask().ptrOr(nullptr), op.opacity(), op.matrix(), op.mixBlendMode());
break;
}
case WebRenderCommand::TOpDPPopStackingContext: {
builder.PopStackingContext();
break;
}
case WebRenderCommand::TOpDPPushScrollLayer: {
const OpDPPushScrollLayer& op = cmd.get_OpDPPushScrollLayer();
builder.PushScrollLayer(op.bounds(), op.overflow(), op.mask().ptrOr(nullptr));
break;
}
case WebRenderCommand::TOpDPPopScrollLayer: {
builder.PopScrollLayer();
break;
}
case WebRenderCommand::TOpDPPushRect: {
const OpDPPushRect& op = cmd.get_OpDPPushRect();
builder.PushRect(op.bounds(), op.clip(), op.color());
break;
}
case WebRenderCommand::TOpDPPushBorder: {
const OpDPPushBorder& op = cmd.get_OpDPPushBorder();
builder.PushBorder(op.bounds(), op.clip(),
op.top(), op.right(), op.bottom(), op.left(),
op.radius());
break;
}
case WebRenderCommand::TOpDPPushLinearGradient: {
const OpDPPushLinearGradient& op = cmd.get_OpDPPushLinearGradient();
builder.PushLinearGradient(op.bounds(), op.clip(),
op.startPoint(), op.endPoint(),
op.stops(), op.extendMode());
break;
}
case WebRenderCommand::TOpDPPushRadialGradient: {
const OpDPPushRadialGradient& op = cmd.get_OpDPPushRadialGradient();
builder.PushRadialGradient(op.bounds(), op.clip(),
op.startCenter(), op.endCenter(),
op.startRadius(), op.endRadius(),
op.stops(), op.extendMode());
break;
}
case WebRenderCommand::TOpDPPushImage: {
const OpDPPushImage& op = cmd.get_OpDPPushImage();
builder.PushImage(op.bounds(), op.clip(),
op.mask().ptrOr(nullptr), op.filter(), wr::ImageKey(op.key()));
break;
}
case WebRenderCommand::TOpDPPushIframe: {
const OpDPPushIframe& op = cmd.get_OpDPPushIframe();
builder.PushIFrame(op.bounds(), op.clip(), op.pipelineId());
break;
}
case WebRenderCommand::TOpDPPushText: {
const OpDPPushText& op = cmd.get_OpDPPushText();
const nsTArray<WrGlyphArray>& glyph_array = op.glyph_array();
for (size_t i = 0; i < glyph_array.Length(); i++) {
const nsTArray<WrGlyphInstance>& glyphs = glyph_array[i].glyphs;
builder.PushText(op.bounds(),
op.clip(),
glyph_array[i].color,
op.key(),
Range<const WrGlyphInstance>(glyphs.Elements(), glyphs.Length()),
op.glyph_size());
}
break;
}
case WebRenderCommand::TOpDPPushBoxShadow: {
const OpDPPushBoxShadow& op = cmd.get_OpDPPushBoxShadow();
builder.PushBoxShadow(op.rect(),
op.clip(),
op.box_bounds(),
op.offset(),
op.color(),
op.blur_radius(),
op.spread_radius(),
op.border_radius(),
op.clip_mode());
break;
}
default:
NS_RUNTIMEABORT("not reached");
}
}
builder.End();
wr::BuiltDisplayList dl;
builder.Finalize(dl.dl_desc, dl.dl, dl.aux_desc, dl.aux);
return dl;
}
void
WebRenderBridgeChild::DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId)
WebRenderBridgeChild::DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
@ -209,7 +89,7 @@ WebRenderBridgeChild::DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aT
}
}
wr::BuiltDisplayList dl = ProcessWebrenderCommands(aSize, mCommands);
wr::BuiltDisplayList dl = aBuilder.Finalize();
ByteBuffer dlData(Move(dl.dl));
ByteBuffer auxData(Move(dl.aux));
@ -221,7 +101,6 @@ WebRenderBridgeChild::DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aT
dlData, dl.dl_desc, auxData, dl.aux_desc);
}
mCommands.Clear();
mParentCommands.Clear();
mDestroyedActors.Clear();
mReadLocks.Clear();

Просмотреть файл

@ -16,6 +16,10 @@ namespace widget {
class CompositorWidget;
}
namespace wr {
class DisplayListBuilder;
}
namespace layers {
class CompositableClient;
@ -30,16 +34,16 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild
public:
explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
void AddWebRenderCommand(const WebRenderCommand& aCmd);
void AddWebRenderCommands(const nsTArray<WebRenderCommand>& aCommands);
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
void AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands);
bool DPBegin(const gfx::IntSize& aSize);
void DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId);
void DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId);
CompositorBridgeChild* GetCompositorBridgeChild();
wr::PipelineId GetPipeline() { return mPipelineId; }
// KnowsCompositor
TextureForwarder* GetTextureForwarder() override;
LayersIPCActor* GetLayersIPCActor() override;
@ -70,9 +74,6 @@ private:
uint64_t GetNextExternalImageId();
wr::BuiltDisplayList ProcessWebrenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderCommand>& aCommands);
// CompositableForwarder
void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer = nullptr) override;
@ -110,7 +111,6 @@ private:
bool AddOpDestroy(const OpDestroy& aOp);
nsTArray<WebRenderCommand> mCommands;
nsTArray<WebRenderParentCommand> mParentCommands;
nsTArray<OpDestroy> mDestroyedActors;
nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;

Просмотреть файл

@ -18,6 +18,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/WebRenderCompositableHolder.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
@ -239,7 +240,7 @@ WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
++mWrEpoch; // Update webrender epoch
ProcessWebrenderCommands(aSize, aCommands, wr::NewEpoch(mWrEpoch),
ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(mWrEpoch),
dl, dlDesc, aux, auxDesc);
HoldPendingTransactionId(mWrEpoch, aTransactionId);
}
@ -277,7 +278,7 @@ WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
}
void
WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
@ -289,14 +290,34 @@ WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
const WebRenderParentCommand& cmd = aCommands[i];
switch (cmd.type()) {
case WebRenderParentCommand::TOpAddExternalImage: {
const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
wr::ImageKey key = op.key();
MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
if (!host) {
NS_ERROR("CompositableHost does not exist");
break;
}
// XXX select Texture for video in CompositeToTarget().
TextureHost* texture = host->GetAsTextureHost();
if (!texture) {
NS_ERROR("TextureHost does not exist");
break;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
// XXX handling YUV
gfx::SurfaceFormat format =
wrTexture->GetFormat() == SurfaceFormat::YUV ? SurfaceFormat::B8G8R8A8 : wrTexture->GetFormat();
wr::ImageDescriptor descriptor(wrTexture->GetSize(), wrTexture->GetRGBStride(), format);
mApi->AddExternalImageBuffer(key,
descriptor,
wrTexture->GetExternalImageKey());
mCompositableHolder->HoldExternalImage(aEpoch, texture->AsWebRenderTextureHost());
keysToDelete.push_back(key);
break;
}
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
@ -310,8 +331,7 @@ WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, SurfaceFormat::B8G8R8A8);
wr::ImageKey key = op.key();
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
mApi->AddImage(key, descriptor, slice);
@ -335,6 +355,10 @@ WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
}
}
}
if (mWidget) {
LayoutDeviceIntSize size = mWidget->GetClientSize();
mApi->SetWindowParameters(size);
}
mApi->SetRootDisplayList(gfx::Color(0.3f, 0.f, 0.f, 1.f), aEpoch, LayerSize(aSize.width, aSize.height),
mPipelineId,
dlDesc, dl.mData, dl.mLength,
@ -427,7 +451,6 @@ WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
return IPC_OK();
}
mCompositableHolder->AddExternalImageId(aImageId, host);
mExternalImageIds.Put(aImageId, host);
return IPC_OK();
@ -450,7 +473,6 @@ WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const uint64_t& aIm
return IPC_OK();
}
mCompositableHolder->AddExternalImageId(aImageId, host);
mExternalImageIds.Put(aImageId, host);
return IPC_OK();
@ -464,7 +486,6 @@ WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
}
MOZ_ASSERT(mExternalImageIds.Get(aImageId).get());
mExternalImageIds.Remove(aImageId);
mCompositableHolder->RemoveExternalImageId(aImageId);
return IPC_OK();
}
@ -530,8 +551,6 @@ WebRenderBridgeParent::FlushPendingTransactionIds()
return id;
}
uint64_t
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
{
@ -544,6 +563,9 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
}
mPendingTransactionIds.pop();
}
mCompositableHolder->Update(aEpoch);
return id;
}
@ -571,13 +593,18 @@ WebRenderBridgeParent::ScheduleComposition()
void
WebRenderBridgeParent::ClearResources()
{
DeleteOldImages();
if (mCompositableHolder) {
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
uint64_t externalImageId = iter.Key();
mCompositableHolder->RemoveExternalImageId(externalImageId);
if (mApi) {
++mWrEpoch; // Update webrender epoch
mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId);
if (!mKeysToDelete.empty()) {
// XXX Sync wait.
mApi->WaitFlushed();
DeleteOldImages();
}
}
if (mCompositableHolder) {
mCompositableHolder->Destroy();
}
mExternalImageIds.Clear();
if (mWidget && mCompositorScheduler) {

Просмотреть файл

@ -152,7 +152,7 @@ private:
virtual ~WebRenderBridgeParent();
void DeleteOldImages();
void ProcessWebrenderCommands(const gfx::IntSize &aSize, InfallibleTArray<WebRenderParentCommand>& commands, const wr::Epoch& aEpoch,
void ProcessWebRenderCommands(const gfx::IntSize &aSize, InfallibleTArray<WebRenderParentCommand>& commands, const wr::Epoch& aEpoch,
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,

Просмотреть файл

@ -46,7 +46,7 @@ WebRenderCanvasLayer::Initialize(const Data& aData)
}
void
WebRenderCanvasLayer::RenderLayer()
WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
UpdateCompositableClient();
@ -61,58 +61,40 @@ WebRenderCanvasLayer::RenderLayer()
if (needsYFlip) {
transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
}
gfx::Rect rect(0, 0, mBounds.width, mBounds.height);
rect = RelativeToVisible(rect);
gfx::Rect clip;
if (GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(IntRectToRect(GetClipRect().ref().ToUnknownRect())));
} else {
clip = rect;
}
gfx::Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Maybe<WrImageMask> mask = buildMaskLayer();
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
gfx::Rect rect = RelativeToVisible(gfx::Rect(0, 0, mBounds.width, mBounds.height));
gfx::Rect clipRect = GetWrClipRect(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer();
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect));
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("CanvasLayer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("CanvasLayer %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, texture-filter=%s, mix-blend-mode=%s\n",
printf_stderr("CanvasLayer %p texture-filter=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(rect).c_str(),
Stringify(clip).c_str(),
Stringify(filter).c_str(),
Stringify(mixBlendMode).c_str());
Stringify(filter).c_str());
}
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask,
1.0f,
GetAnimations(),
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, key));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask.ptrOr(nullptr),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
aBuilder.PopStackingContext();
}
void

Просмотреть файл

@ -45,7 +45,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
protected:
uint64_t mExternalImageId;

Просмотреть файл

@ -17,59 +17,31 @@ namespace layers {
using namespace mozilla::gfx;
void
WebRenderColorLayer::RenderLayer()
WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
WrScrollFrameStackingContextGenerator scrollFrames(this);
gfx::Matrix4x4 transform = GetTransform();
LayerIntRegion visibleRegion = GetVisibleRegion();
LayerIntRect bounds = visibleRegion.GetBounds();
Rect rect(0, 0, bounds.width, bounds.height);
Rect clip;
if (GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(IntRectToRect(GetClipRect().ref().ToUnknownRect())));
} else {
clip = rect;
}
gfx::Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
Maybe<WrImageMask> mask = buildMaskLayer();
gfx::Rect rect = GetWrBoundsRect();
gfx::Rect clipRect = GetWrClipRect(rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("ColorLayer %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(rect).c_str(),
Stringify(clip).c_str(),
Stringify(mixBlendMode).c_str());
}
Maybe<WrImageMask> mask = BuildWrMaskLayer();
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect));
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("ColorLayer", rect);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask,
mask.ptrOr(nullptr),
1.0f,
GetAnimations(),
//GetAnimations(),
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand(
OpDPPushRect(wr::ToWrRect(rect), wr::ToWrRect(clip), wr::ToWrColor(mColor)));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
mixBlendMode);
aBuilder.PushRect(wr::ToWrRect(rect), clip, wr::ToWrColor(mColor));
aBuilder.PopStackingContext();
}
} // namespace layers

Просмотреть файл

@ -29,7 +29,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
};
} // namespace layers

Просмотреть файл

@ -6,7 +6,8 @@
#include "WebRenderCompositableHolder.h"
#include "CompositableHost.h"
//#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/WebRenderImageHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
namespace mozilla {
@ -22,36 +23,36 @@ WebRenderCompositableHolder::WebRenderCompositableHolder()
WebRenderCompositableHolder::~WebRenderCompositableHolder()
{
MOZ_COUNT_DTOR(WebRenderCompositableHolder);
Destroy();
MOZ_ASSERT(mWebRenderTextureHosts.empty());
}
void
WebRenderCompositableHolder::Destroy()
{
mCompositableHosts.Clear();
while (!mWebRenderTextureHosts.empty()) {
mWebRenderTextureHosts.pop();
}
}
void
WebRenderCompositableHolder::AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost)
WebRenderCompositableHolder::HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
{
MOZ_ASSERT(!mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Put(aExternalImageId, aHost);
MOZ_ASSERT(aTexture);
// Hold WebRenderTextureHost until end of its usage on RenderThread
mWebRenderTextureHosts.push(ForwardingTextureHosts(aEpoch, aTexture));
}
void
WebRenderCompositableHolder::RemoveExternalImageId(uint64_t aExternalImageId)
WebRenderCompositableHolder::Update(const wr::Epoch& aEpoch)
{
MOZ_ASSERT(mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Remove(aExternalImageId);
}
void
WebRenderCompositableHolder::UpdateExternalImages()
{
for (auto iter = mCompositableHosts.Iter(); !iter.Done(); iter.Next()) {
RefPtr<CompositableHost>& host = iter.Data();
// XXX Change to correct TextrueSource handling here.
host->BindTextureSource();
if (mWebRenderTextureHosts.empty()) {
return;
}
while (!mWebRenderTextureHosts.empty()) {
if (aEpoch <= mWebRenderTextureHosts.front().mEpoch) {
break;
}
mWebRenderTextureHosts.pop();
}
}

Просмотреть файл

@ -6,12 +6,21 @@
#ifndef MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
#define MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
#include "nsDataHashtable.h"
#include <queue>
#include "mozilla/layers/TextureHost.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace wr {
class WebRenderAPI;
}
namespace layers {
class CompositableHost;
class WebRenderTextureHost;
class WebRenderCompositableHolder final
{
@ -21,20 +30,26 @@ public:
explicit WebRenderCompositableHolder();
protected:
virtual ~WebRenderCompositableHolder();
~WebRenderCompositableHolder();
public:
virtual void Destroy();
void AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost);
void RemoveExternalImageId(uint64_t aExternalImageId);
void UpdateExternalImages();
void Destroy();
void HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
void Update(const wr::Epoch& aEpoch);
private:
// Holds CompositableHosts that are bound to external image ids.
nsDataHashtable<nsUint64HashKey, RefPtr<CompositableHost> > mCompositableHosts;
struct ForwardingTextureHosts {
ForwardingTextureHosts(const wr::Epoch& aEpoch, TextureHost* aTexture)
: mEpoch(aEpoch)
, mTexture(aTexture)
{}
wr::Epoch mEpoch;
CompositableTextureHostRef mTexture;
};
// Holds forwarding WebRenderTextureHosts.
std::queue<ForwardingTextureHosts> mWebRenderTextureHosts;
};
} // namespace layers

Просмотреть файл

@ -15,25 +15,17 @@ namespace mozilla {
namespace layers {
void
WebRenderContainerLayer::RenderLayer()
WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
WrScrollFrameStackingContextGenerator scrollFrames(this);
nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
Maybe<WrImageMask> mask = buildMaskLayer();
Maybe<WrImageMask> mask = BuildWrMaskLayer();
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
if (gfxPrefs::LayersDump()) {
printf_stderr("ContainerLayer %p using bounds=%s, overflow=%s, transform=%s, mix-blend-mode=%s\n",
@ -43,33 +35,29 @@ WebRenderContainerLayer::RenderLayer()
Stringify(transform).c_str(),
Stringify(mixBlendMode).c_str());
}
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask,
GetLocalOpacity(),
GetLayer()->GetAnimations(),
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask.ptrOr(nullptr),
GetLocalOpacity(),
//GetLayer()->GetAnimations(),
transform,
mixBlendMode);
for (LayerPolygon& child : children) {
if (child.layer->IsBackfaceHidden()) {
continue;
}
ToWebRenderLayer(child.layer)->RenderLayer();
ToWebRenderLayer(child.layer)->RenderLayer(aBuilder);
}
WrBridge()->AddWebRenderCommand(
OpDPPopStackingContext());
aBuilder.PopStackingContext();
}
void
WebRenderRefLayer::RenderLayer()
WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
WrScrollFrameStackingContextGenerator scrollFrames(this);
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Matrix4x4 transform;// = GetTransform();
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(relBounds));
if (gfxPrefs::LayersDump()) {
printf_stderr("RefLayer %p (%" PRIu64 ") using bounds/overflow=%s, transform=%s\n",
@ -79,7 +67,7 @@ WebRenderRefLayer::RenderLayer()
Stringify(transform).c_str());
}
WrBridge()->AddWebRenderCommand(OpDPPushIframe(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), wr::AsPipelineId(mId)));
aBuilder.PushIFrame(wr::ToWrRect(relBounds), clipRegion, wr::AsPipelineId(mId));
}
} // namespace layers

Просмотреть файл

@ -31,7 +31,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
@ -56,7 +56,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{

Просмотреть файл

@ -16,18 +16,19 @@ namespace mozilla {
namespace layers {
void
WebRenderDisplayItemLayer::RenderLayer()
WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
if (mItem) {
wr::DisplayListBuilder builder(WrBridge()->GetPipeline());
// We might have recycled this layer. Throw away the old commands.
mCommands.Clear();
mParentCommands.Clear();
mItem->CreateWebRenderCommands(mCommands, mParentCommands, this);
mItem->CreateWebRenderCommands(builder, mParentCommands, this);
mBuiltDisplayList = builder.Finalize();
}
// else we have an empty transaction and just use the
// old commands.
WrBridge()->AddWebRenderCommands(mCommands);
aBuilder.PushBuiltDisplayList(Move(mBuiltDisplayList));
WrBridge()->AddWebRenderParentCommands(mParentCommands);
}

Просмотреть файл

@ -29,16 +29,15 @@ public:
protected:
virtual ~WebRenderDisplayItemLayer()
{
mCommands.Clear();
MOZ_COUNT_DTOR(WebRenderDisplayItemLayer);
}
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
private:
nsTArray<WebRenderCommand> mCommands;
wr::BuiltDisplayList mBuiltDisplayList;
nsTArray<WebRenderParentCommand> mParentCommands;
RefPtr<ImageClient> mImageClient;
RefPtr<ImageContainer> mImageContainer;

Просмотреть файл

@ -102,7 +102,10 @@ WebRenderImageHost::GetCompositionTime() const
TextureHost*
WebRenderImageHost::GetAsTextureHost(IntRect* aPictureRect)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
TimedImage* img = ChooseImage();
if (img) {
return img->mTextureHost;
}
return nullptr;
}

Просмотреть файл

@ -62,6 +62,8 @@ public:
virtual void CleanupResources() override;
virtual WebRenderImageHost* AsWebRenderImageHost() override { return this; }
protected:
// ImageComposite
virtual TimeStamp GetCompositionTime() const override;

Просмотреть файл

@ -80,7 +80,7 @@ WebRenderImageLayer::ClearCachedResources()
}
void
WebRenderImageLayer::RenderLayer()
WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
if (!mContainer) {
return;
@ -127,62 +127,108 @@ WebRenderImageLayer::RenderLayer()
return;
}
WrScrollFrameStackingContextGenerator scrollFrames(this);
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Matrix4x4 transform = GetTransform();
Rect rect(0, 0, size.width, size.height);
Rect clip;
if (GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(IntRectToRect(GetClipRect().ref().ToUnknownRect())));
} else {
clip = rect;
gfx::Rect rect = gfx::Rect(0, 0, size.width, size.height);
if (mScaleMode != ScaleMode::SCALE_NONE) {
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
"No other scalemodes than stretch and none supported yet.");
rect = gfx::Rect(0, 0, mScaleToSize.width, mScaleToSize.height);
}
rect = RelativeToVisible(rect);
gfx::Rect clipRect = GetWrClipRect(rect);
Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
Maybe<WrImageMask> mask = BuildWrMaskLayer();
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect));
Rect overflow(0, 0, relBounds.width, relBounds.height);
Maybe<WrImageMask> mask = buildMaskLayer();
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("Image Layer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("ImageLayer %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, texture-filter=%s, mix-blend-mode=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(rect).c_str(),
Stringify(clip).c_str(),
Stringify(filter).c_str(),
Stringify(mixBlendMode).c_str());
printf_stderr("ImageLayer %p texture-filter=%s \n",
GetLayer(),
Stringify(filter).c_str());
}
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask,
1.0f,
GetAnimations(),
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, key));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask.ptrOr(nullptr),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
aBuilder.PopStackingContext();
//mContainer->SetImageFactory(originalIF);
}
Maybe<WrImageMask>
WebRenderImageLayer::RenderMaskLayer()
{
if (!mContainer) {
return Nothing();
}
CompositableType type = GetImageClientType();
if (type == CompositableType::UNKNOWN) {
return Nothing();
}
MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);
if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
WrBridge(),
TextureFlags::DEFAULT);
if (!mImageClient) {
return Nothing();
}
mImageClient->Connect();
}
if (!mExternalImageId) {
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
MOZ_ASSERT(!mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle());
} else {
// Handle CompositableType::IMAGE case
MOZ_ASSERT(mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
}
}
MOZ_ASSERT(mExternalImageId);
// XXX Not good for async ImageContainer case.
AutoLockImage autoLock(mContainer);
Image* image = autoLock.GetImage();
if (!image) {
return Nothing();
}
if (mImageClient && !mImageClient->UpdateImage(mContainer, /* unused */0)) {
return Nothing();
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
gfx::IntSize size = image->GetSize();
WrImageMask imageMask;
imageMask.image = key;
imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
imageMask.repeat = false;
return Some(imageMask);
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -32,7 +32,8 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
Maybe<WrImageMask> RenderMaskLayer() override;
protected:
CompositableType GetImageClientType();

Просмотреть файл

@ -109,92 +109,80 @@ WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
}
Maybe<WrImageMask>
WebRenderLayer::buildMaskLayer() {
Maybe<WrImageMask> mask = Nothing();
WrImageMask imageMask;
Layer* maskLayer = GetLayer()->GetMaskLayer();
if (maskLayer) {
RefPtr<SourceSurface> surface = WebRenderLayer::ToWebRenderLayer(maskLayer)->GetAsSourceSurface();
if (surface) {
Matrix transform;
Matrix4x4 effectiveTransform = maskLayer->GetEffectiveTransform();
DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
//XXX: let's assert that the mask transform is the same as the layer transform
//transform.PostTranslate(-aDeviceOffset.x, -aDeviceOffset.y);
{
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::MapType::READ);
gfx::IntSize size = surface->GetSize();
MOZ_RELEASE_ASSERT(surface->GetFormat() == SurfaceFormat::A8, "bad format");
wr::ByteBuffer buf(size.height * map.GetStride(), map.GetData());
WrImageKey maskKey;
maskKey.mNamespace = WrBridge()->GetNamespace();
maskKey.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->SendAddImage(maskKey, size, map.GetStride(), SurfaceFormat::A8, buf);
imageMask.image = maskKey;
imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
imageMask.repeat = false;
WrManager()->AddImageKeyForDiscard(maskKey);
mask = Some(imageMask);
}
}
}
return mask;
}
WrScrollFrameStackingContextGenerator::WrScrollFrameStackingContextGenerator(
WebRenderLayer* aLayer)
: mLayer(aLayer)
WebRenderLayer::BuildWrMaskLayer()
{
Matrix4x4 identity;
Layer* layer = mLayer->GetLayer();
for (size_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
if (!fm.IsScrollable()) {
continue;
}
Rect bounds = fm.GetCompositionBounds().ToUnknownRect();
Rect overflow = (fm.GetExpandedScrollableRect() * fm.LayersPixelsPerCSSPixel()).ToUnknownRect();
Point scrollPos = (fm.GetScrollOffset() * fm.LayersPixelsPerCSSPixel()).ToUnknownPoint();
Rect parentBounds = mLayer->ParentStackingContextBounds(i);
bounds.MoveBy(-parentBounds.x, -parentBounds.y);
// Subtract the MT scroll position from the overflow here so that the WR
// scroll offset (which is the APZ async scroll component) always fits in
// the available overflow. If we didn't do this and WR did bounds checking
// on the scroll offset, we'd fail those checks.
overflow.MoveBy(bounds.x - scrollPos.x, bounds.y - scrollPos.y);
if (gfxPrefs::LayersDump()) {
printf_stderr("Pushing stacking context id %" PRIu64 " with bounds=%s, overflow=%s\n",
fm.GetScrollId(), Stringify(bounds).c_str(), Stringify(overflow).c_str());
}
/* mLayer->WrBridge()->AddWebRenderCommand(
OpDPPushScrollLayer(wr::ToWrRect(bounds),
wr::ToWrRect(overflow),
Nothing(),
fm.GetScrollId()));*/
if (GetLayer()->GetMaskLayer()) {
WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
return maskLayer->RenderMaskLayer();
}
return Nothing();
}
WrScrollFrameStackingContextGenerator::~WrScrollFrameStackingContextGenerator()
gfx::Rect
WebRenderLayer::GetWrBoundsRect()
{
Layer* layer = mLayer->GetLayer();
for (size_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
const FrameMetrics& fm = layer->GetFrameMetrics(i);
if (!fm.IsScrollable()) {
continue;
}
if (gfxPrefs::LayersDump()) printf_stderr("Popping stacking context id %" PRIu64"\n", fm.GetScrollId());
// mLayer->WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
}
LayerIntRect bounds = GetLayer()->GetVisibleRegion().GetBounds();
return Rect(0, 0, bounds.width, bounds.height);
}
gfx::Rect
WebRenderLayer::GetWrClipRect(gfx::Rect& aRect)
{
gfx::Rect clip;
Layer* layer = GetLayer();
Matrix4x4 transform = layer->GetTransform();
if (layer->GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(
IntRectToRect(layer->GetClipRect().ref().ToUnknownRect()))
);
} else {
clip = aRect;
}
return clip;
}
gfx::Rect
WebRenderLayer::GetWrRelBounds()
{
gfx::Rect relBounds = VisibleBoundsRelativeToParent();
gfx::Matrix4x4 transform = GetLayer()->GetTransform();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
return relBounds;
}
void
WebRenderLayer::DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect)
{
if (!gfxPrefs::LayersDump()) {
return;
}
Matrix4x4 transform = GetLayer()->GetTransform();
Rect clip = GetWrClipRect(aRect);
Rect relBounds = GetWrRelBounds();
Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetLayer()->GetMixBlendMode());
printf_stderr("%s %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
aLayerType,
GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(aRect).c_str(),
Stringify(clip).c_str(),
Stringify(mixBlendMode).c_str());
}
WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
: mWidget(aWidget)
@ -218,14 +206,15 @@ WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild,
MOZ_ASSERT(mWrChild == nullptr);
MOZ_ASSERT(aTextureFactoryIdentifier);
LayoutDeviceIntSize size = mWidget->GetClientSize();
TextureFactoryIdentifier textureFactoryIdentifier;
uint32_t id_namespace;
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId,
size,
&textureFactoryIdentifier,
&id_namespace);
MOZ_ASSERT(bridge);
mWrChild = static_cast<WebRenderBridgeChild*>(bridge);
LayoutDeviceIntSize size = mWidget->GetClientSize();
WrBridge()->SendCreate(size.ToUnknownSize());
WrBridge()->IdentifyTextureHost(textureFactoryIdentifier);
WrBridge()->SetNamespace(id_namespace);
@ -316,12 +305,13 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
return;
}
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer();
wr::DisplayListBuilder builder(WrBridge()->GetPipeline());
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder);
bool sync = mTarget != nullptr;
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();
WrBridge()->DPEnd(size.ToUnknownSize(), sync, mLatestTransactionId);
WrBridge()->DPEnd(builder, size.ToUnknownSize(), sync, mLatestTransactionId);
MakeSnapshotIfRequired(size);
@ -346,7 +336,7 @@ WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
SurfaceFormat::B8G8R8A8,
aSize.ToUnknownSize(),
BackendType::SKIA,
TextureFlags::DEFAULT);
TextureFlags::SNAPSHOT);
if (!texture) {
return;
}

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/layers/TransactionIdAllocator.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
class nsIWidget;
@ -28,7 +29,12 @@ class WebRenderLayer
{
public:
virtual Layer* GetLayer() = 0;
virtual void RenderLayer() = 0;
virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0;
virtual Maybe<WrImageMask> RenderMaskLayer()
{
MOZ_ASSERT(false);
return Nothing();
}
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
static inline WebRenderLayer*
@ -48,17 +54,11 @@ public:
gfx::Point GetOffsetToParent();
gfx::Rect TransformedVisibleBoundsRelativeToParent();
protected:
Maybe<WrImageMask> buildMaskLayer();
};
class MOZ_RAII WrScrollFrameStackingContextGenerator
{
public:
explicit WrScrollFrameStackingContextGenerator(WebRenderLayer* aLayer);
~WrScrollFrameStackingContextGenerator();
private:
WebRenderLayer* mLayer;
gfx::Rect GetWrBoundsRect();
gfx::Rect GetWrRelBounds();
gfx::Rect GetWrClipRect(gfx::Rect& aRect);
void DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect);
Maybe<WrImageMask> BuildWrMaskLayer();
};
class WebRenderLayerManager final : public LayerManager

Просмотреть файл

@ -99,174 +99,23 @@ struct ParamTraits<WrImageFormat>
};
template<>
struct ParamTraits<WrBorderStyle>
: public ContiguousEnumSerializer<
WrBorderStyle,
WrBorderStyle::None,
WrBorderStyle::Sentinel>
{
};
template<>
struct ParamTraits<WrColor>
struct ParamTraits<WrSize>
{
static void
Write(Message* aMsg, const WrColor& aParam)
{
WriteParam(aMsg, aParam.r);
WriteParam(aMsg, aParam.g);
WriteParam(aMsg, aParam.b);
WriteParam(aMsg, aParam.a);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrColor* aResult)
{
return ReadParam(aMsg, aIter, &aResult->r)
&& ReadParam(aMsg, aIter, &aResult->g)
&& ReadParam(aMsg, aIter, &aResult->b)
&& ReadParam(aMsg, aIter, &aResult->a);
}
};
template<>
struct ParamTraits<WrGlyphInstance>
{
static void
Write(Message* aMsg, const WrGlyphInstance& aParam)
{
WriteParam(aMsg, aParam.index);
WriteParam(aMsg, aParam.x);
WriteParam(aMsg, aParam.y);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrGlyphInstance* aResult)
{
return ReadParam(aMsg, aIter, &aResult->index)
&& ReadParam(aMsg, aIter, &aResult->x)
&& ReadParam(aMsg, aIter, &aResult->y);
}
};
template<>
struct ParamTraits<WrGlyphArray>
{
static void
Write(Message* aMsg, const WrGlyphArray& aParam)
{
WriteParam(aMsg, aParam.color);
size_t length = aParam.glyphs.Length();
WriteParam(aMsg, length);
for (size_t i = 0; i < length; i++) {
WriteParam(aMsg, aParam.glyphs[i]);
}
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrGlyphArray* aResult)
{
if (!ReadParam(aMsg, aIter, &aResult->color)) {
return false;
}
size_t length;
if (!ReadParam(aMsg, aIter, &length)) {
return false;
}
aResult->glyphs.SetLength(length);
for (size_t i = 0; i < length; i++) {
if (!ReadParam(aMsg, aIter, &aResult->glyphs[i])) {
return false;
}
}
return true;
}
};
template<>
struct ParamTraits<WrGradientStop>
{
static void
Write(Message* aMsg, const WrGradientStop& aParam)
{
WriteParam(aMsg, aParam.offset);
WriteParam(aMsg, aParam.color);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrGradientStop* aResult)
{
return ReadParam(aMsg, aIter, &aResult->offset)
&& ReadParam(aMsg, aIter, &aResult->color);
}
};
template<>
struct ParamTraits<WrBorderSide>
{
static void
Write(Message* aMsg, const WrBorderSide& aParam)
{
WriteParam(aMsg, aParam.width);
WriteParam(aMsg, aParam.color);
WriteParam(aMsg, aParam.style);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrBorderSide* aResult)
{
return ReadParam(aMsg, aIter, &aResult->width)
&& ReadParam(aMsg, aIter, &aResult->color)
&& ReadParam(aMsg, aIter, &aResult->style);
}
};
template<>
struct ParamTraits<WrLayoutSize>
{
static void
Write(Message* aMsg, const WrLayoutSize& aParam)
Write(Message* aMsg, const WrSize& aParam)
{
WriteParam(aMsg, aParam.width);
WriteParam(aMsg, aParam.height);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrLayoutSize* aResult)
Read(const Message* aMsg, PickleIterator* aIter, WrSize* aResult)
{
return ReadParam(aMsg, aIter, &aResult->width)
&& ReadParam(aMsg, aIter, &aResult->height);
}
};
template<>
struct ParamTraits<WrBorderRadius>
{
static void
Write(Message* aMsg, const WrBorderRadius& aParam)
{
WriteParam(aMsg, aParam.top_left);
WriteParam(aMsg, aParam.top_right);
WriteParam(aMsg, aParam.bottom_left);
WriteParam(aMsg, aParam.bottom_right);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrBorderRadius* aResult)
{
return ReadParam(aMsg, aIter, &aResult->top_left)
&& ReadParam(aMsg, aIter, &aResult->top_right)
&& ReadParam(aMsg, aIter, &aResult->bottom_left)
&& ReadParam(aMsg, aIter, &aResult->bottom_right);
}
};
template<>
struct ParamTraits<WrRect>
{
@ -307,26 +156,6 @@ struct ParamTraits<WrPoint>
}
};
template<>
struct ParamTraits<WrImageMask>
{
static void
Write(Message* aMsg, const WrImageMask& aParam)
{
WriteParam(aMsg, aParam.image);
WriteParam(aMsg, aParam.rect);
WriteParam(aMsg, aParam.repeat);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrImageMask* aResult)
{
return ReadParam(aMsg, aIter, &aResult->image)
&& ReadParam(aMsg, aIter, &aResult->rect)
&& ReadParam(aMsg, aIter, &aResult->repeat);
}
};
template<>
struct ParamTraits<WrBuiltDisplayListDescriptor>
{
@ -365,43 +194,6 @@ struct ParamTraits<WrAuxiliaryListsDescriptor>
}
};
template<>
struct ParamTraits<WrImageRendering>
: public ContiguousEnumSerializer<
WrImageRendering,
WrImageRendering::Auto,
WrImageRendering::Sentinel>
{
};
template<>
struct ParamTraits<WrMixBlendMode>
: public ContiguousEnumSerializer<
WrMixBlendMode,
WrMixBlendMode::Normal,
WrMixBlendMode::Sentinel>
{
};
template<>
struct ParamTraits<WrBoxShadowClipMode>
: public ContiguousEnumSerializer<
WrBoxShadowClipMode,
WrBoxShadowClipMode::None,
WrBoxShadowClipMode::Sentinel>
{
};
template<>
struct ParamTraits<WrGradientExtendMode>
: public ContiguousEnumSerializer<
WrGradientExtendMode,
WrGradientExtendMode::Clamp,
WrGradientExtendMode::Sentinel>
{
};
} // namespace IPC
#endif // GFX_WEBRENDERMESSAGEUTILS_H

Просмотреть файл

@ -114,7 +114,7 @@ WebRenderPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback)
}
void
WebRenderPaintedLayer::RenderLayer()
WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
// XXX We won't keep using ContentClient for WebRenderPaintedLayer in the future and
// there is a crash problem for ContentClient on MacOS. So replace ContentClient with
@ -182,63 +182,36 @@ WebRenderPaintedLayer::RenderLayer()
mImageContainer->SetCurrentImageInTransaction(image);
if (!mImageClient->UpdateImage(mImageContainer, /* unused */0)) {
return;
}
WrScrollFrameStackingContextGenerator scrollFrames(this);
Matrix4x4 transform = GetTransform();
// Since we are creating a stacking context below using the visible region of
// this layer, we need to make sure the image display item has coordinates
// relative to the visible region.
Rect rect(0, 0, size.width, size.height);
Rect clip;
if (GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(IntRectToRect(GetClipRect().ref().ToUnknownRect())));
} else {
clip = rect;
}
Maybe<WrImageMask> mask = buildMaskLayer();
Rect relBounds = VisibleBoundsRelativeToParent();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
gfx::Matrix4x4 boundTransform = transform;
boundTransform._41 = 0.0f;
boundTransform._42 = 0.0f;
boundTransform._43 = 0.0f;
relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
}
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
gfx::Rect rect(0, 0, size.width, size.height);
gfx::Rect clipRect = GetWrClipRect(rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("PaintedLayer %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(rect).c_str(),
Stringify(clip).c_str(),
Stringify(mixBlendMode).c_str());
}
Maybe<WrImageMask> mask = BuildWrMaskLayer();
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect));
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("PaintedLayer", rect);
WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask,
1.0f,
GetAnimations(),
transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID));
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), wr::ImageRendering::Auto, key));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
mask.ptrOr(nullptr),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, wr::ImageRendering::Auto, key);
aBuilder.PopStackingContext();
}
} // namespace layers

Просмотреть файл

@ -51,7 +51,7 @@ public:
}
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
void PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates);
void RenderLayerWithReadback(ReadbackProcessor *aReadback);
RefPtr<ContentClient> mContentClient;

Просмотреть файл

@ -18,7 +18,7 @@ namespace layers {
using namespace mozilla::gfx;
void
WebRenderTextLayer::RenderLayer()
WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
if (mBounds.IsEmpty()) {
return;
@ -39,10 +39,8 @@ WebRenderTextLayer::RenderLayer()
Stringify(clip).c_str());
}
nsTArray<WebRenderCommand> commands;
mGlyphHelper.BuildWebRenderCommands(WrBridge(), commands, mGlyphs, mFont,
mGlyphHelper.BuildWebRenderCommands(WrBridge(), aBuilder, mGlyphs, mFont,
GetOffsetToParent(), rect, clip);
WrBridge()->AddWebRenderCommands(commands);
}
} // namespace layers

Просмотреть файл

@ -31,7 +31,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer() override;
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
protected:
gfx::WebRenderGlyphHelper mGlyphHelper;
@ -40,4 +40,4 @@ protected:
} // namespace layers
} // namespace mozilla
#endif // GFX_WEBRENDERTEXTLAYER_H
#endif // GFX_WEBRENDERTEXTLAYER_H

Просмотреть файл

@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebRenderTextureHost.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/webrender/RenderThread.h"
namespace mozilla {
namespace layers {
uint64_t WebRenderTextureHost::sSerialCounter(0);
WebRenderTextureHost::WebRenderTextureHost(TextureFlags aFlags,
TextureHost* aTexture)
: TextureHost(aFlags)
, mExternalImageId(++sSerialCounter)
{
MOZ_COUNT_CTOR(WebRenderTextureHost);
mWrappedTextureHost = aTexture;
// XXX support only BufferTextureHost for now.
BufferTextureHost* bufferTexture = aTexture->AsBufferTextureHost();
MOZ_ASSERT(bufferTexture);
RefPtr<wr::RenderTextureHost> texture =
new wr::RenderTextureHost(bufferTexture->GetBuffer(),
bufferTexture->GetBufferDescriptor());
wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId, texture);
}
WebRenderTextureHost::~WebRenderTextureHost()
{
MOZ_COUNT_DTOR(WebRenderTextureHost);
wr::RenderThread::Get()->UnregisterExternalImage(mExternalImageId);
}
bool
WebRenderTextureHost::Lock()
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return false;
}
void
WebRenderTextureHost::Unlock()
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return;
}
bool
WebRenderTextureHost::BindTextureSource(CompositableTextureSourceRef& aTexture)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return false;
}
already_AddRefed<gfx::DataSourceSurface>
WebRenderTextureHost::GetAsSurface()
{
if (!mWrappedTextureHost) {
return nullptr;
}
return mWrappedTextureHost->GetAsSurface();
}
Compositor*
WebRenderTextureHost::GetCompositor()
{
//MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
void
WebRenderTextureHost::SetCompositor(Compositor* aCompositor)
{
}
YUVColorSpace
WebRenderTextureHost::GetYUVColorSpace() const
{
if (mWrappedTextureHost) {
return mWrappedTextureHost->GetYUVColorSpace();
}
return YUVColorSpace::UNKNOWN;
}
gfx::IntSize
WebRenderTextureHost::GetSize() const
{
if (!mWrappedTextureHost) {
return gfx::IntSize();
}
return mWrappedTextureHost->GetSize();
}
gfx::SurfaceFormat
WebRenderTextureHost::GetFormat() const
{
if (!mWrappedTextureHost) {
return gfx::SurfaceFormat::UNKNOWN;
}
return mWrappedTextureHost->GetFormat();
}
int32_t
WebRenderTextureHost::GetRGBStride()
{
if (!mWrappedTextureHost) {
return 0;
}
gfx::SurfaceFormat format = GetFormat();
if (GetFormat() == SurfaceFormat::YUV) {
// XXX this stride is used until yuv image rendering by webrender is used.
// Software converted RGB buffers strides are aliened to 16
return GetAlignedStride<16>(GetSize().width, BytesPerPixel(SurfaceFormat::B8G8R8A8));
}
return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
#define MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {
class WebRenderTextureHost : public TextureHost
{
public:
WebRenderTextureHost(TextureFlags aFlags,
TextureHost* aTexture);
virtual ~WebRenderTextureHost();
virtual void DeallocateDeviceData() override {}
virtual void SetCompositor(Compositor* aCompositor) override;
virtual Compositor* GetCompositor() override;
virtual bool Lock() override;
virtual void Unlock() override;
virtual gfx::SurfaceFormat GetFormat() const override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
virtual YUVColorSpace GetYUVColorSpace() const override;
virtual gfx::IntSize GetSize() const override;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() override { return "WebRenderTextureHost"; }
#endif
virtual WebRenderTextureHost* AsWebRenderTextureHost() override { return this; }
uint64_t GetExternalImageKey() { return mExternalImageId; }
int32_t GetRGBStride();
protected:
RefPtr<TextureHost> mWrappedTextureHost;
uint64_t mExternalImageId;
static uint64_t sSerialCounter;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_WEBRENDERTEXTUREHOST_H

Просмотреть файл

@ -148,6 +148,7 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
// host deserialization
RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr,
LayersBackend::LAYERS_NONE,
texture->GetFlags());
ASSERT_TRUE(host.get() != nullptr);
@ -192,6 +193,7 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
// host deserialization
RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr,
LayersBackend::LAYERS_NONE,
client->GetFlags());
RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());

Просмотреть файл

@ -460,13 +460,15 @@ private:
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
DECL_GFX_PREF(Once, "layers.acceleration.force-enabled", LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.border-layers", LayersAllowBorderLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.text-layers", LayersAllowTextLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.text-layers", LayersAllowTextLayers, bool, false);
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);

Просмотреть файл

@ -27,6 +27,7 @@
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/Vector.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "nsComponentManagerUtils.h"
#include "nsIClipboardHelper.h"
@ -1460,7 +1461,7 @@ WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
void
WebRenderGlyphHelper::BuildWebRenderCommands(WebRenderBridgeChild* aBridge,
nsTArray<WebRenderCommand>& aCommands,
wr::DisplayListBuilder& aBuilder,
const nsTArray<GlyphArray>& aGlyphs,
ScaledFont* aFont,
const Point& aOffset,
@ -1481,30 +1482,28 @@ WebRenderGlyphHelper::BuildWebRenderCommands(WebRenderBridgeChild* aBridge,
aBridge->SendAddRawFont(key, fontBuffer, mIndex);
nsTArray<WrGlyphArray> wr_glyphs;
wr_glyphs.SetLength(aGlyphs.Length());
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(aClip));
for (size_t i = 0; i < aGlyphs.Length(); i++) {
GlyphArray glyph_array = aGlyphs[i];
nsTArray<gfx::Glyph>& glyphs = glyph_array.glyphs();
nsTArray<WrGlyphInstance>& wr_glyph_instances = wr_glyphs[i].glyphs;
nsTArray<WrGlyphInstance> wr_glyph_instances;
wr_glyph_instances.SetLength(glyphs.Length());
wr_glyphs[i].color = glyph_array.color().value();
for (size_t j = 0; j < glyphs.Length(); j++) {
wr_glyph_instances[j].index = glyphs[j].mIndex;
wr_glyph_instances[j].x = glyphs[j].mPosition.x - aOffset.x;
wr_glyph_instances[j].y = glyphs[j].mPosition.y - aOffset.y;
}
}
aBuilder.PushText(wr::ToWrRect(aBounds),
clipRegion,
glyph_array.color().value(),
key,
Range<const WrGlyphInstance>(wr_glyph_instances.Elements(), wr_glyph_instances.Length()),
mGlyphSize);
aCommands.AppendElement(OpDPPushText(
wr::ToWrRect(aBounds),
wr::ToWrRect(aClip),
wr_glyphs,
mGlyphSize,
key));
}
}
} // namespace gfx

Просмотреть файл

@ -35,6 +35,9 @@ class WebRenderCommand;
namespace image {
class ImageRegion;
} // namespace image
namespace wr {
class DisplayListBuilder;
} // namespace wr
} // namespace mozilla
class gfxUtils {
@ -328,7 +331,7 @@ public:
}
void BuildWebRenderCommands(layers::WebRenderBridgeChild* aChild,
nsTArray<layers::WebRenderCommand>& aCommands,
wr::DisplayListBuilder& aBuilder,
const nsTArray<layers::GlyphArray>& aGlyphs,
ScaledFont* aFont,
const Point& aOffset,

Просмотреть файл

@ -1,16 +1,14 @@
[package]
name = "webrender"
version = "0.19.0"
version = "0.24.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
build = "build.rs"
[features]
default = ["codegen", "freetype-lib"]
codegen = ["webrender_traits/codegen"]
default = ["freetype-lib"]
freetype-lib = ["freetype/servo-freetype-sys"]
serde_derive = ["webrender_traits/serde_derive"]
profiler = ["thread_profiler/thread_profiler"]
[dependencies]
@ -19,7 +17,7 @@ bincode = "1.0.0-alpha2"
bit-set = "0.4"
byteorder = "1.0"
euclid = "0.11"
fnv="1.0"
fnv = "1.0"
gleam = "0.2.30"
lazy_static = "0.2"
log = "0.3"
@ -27,7 +25,7 @@ num-traits = "0.1.32"
offscreen_gl_context = {version = "0.6", features = ["serde", "osmesa"]}
time = "0.1"
threadpool = "1.3.2"
webrender_traits = {path = "../webrender_traits", default-features = false}
webrender_traits = {path = "../webrender_traits"}
bitflags = "0.7"
gamma-lut = "0.1"
thread_profiler = "0.1.1"
@ -39,7 +37,7 @@ angle = {git = "https://github.com/servo/angle", branch = "servo"}
freetype = { version = "0.2", default-features = false }
[target.'cfg(target_os = "windows")'.dependencies]
servo-dwrote = "0.2"
dwrote = "0.3"
[target.'cfg(target_os = "macos")'.dependencies]
core-graphics = "0.7.0"

Просмотреть файл

@ -625,12 +625,9 @@ struct YuvImage {
YuvImage fetch_yuv_image(int index) {
YuvImage image;
ivec2 uv = get_fetch_uv_4(index);
ivec2 uv = get_fetch_uv_1(index);
image.y_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(0, 0));
image.u_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(1, 0));
image.v_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(2, 0));
vec4 size_color_space = texelFetchOffset(sData64, uv, 0, ivec2(3, 0));
vec4 size_color_space = texelFetchOffset(sData16, uv, 0, ivec2(0, 0));
image.size = size_color_space.xy;
image.color_space = int(size_color_space.z);

Просмотреть файл

@ -151,6 +151,22 @@ vec3 Luminosity(vec3 Cb, vec3 Cs) {
return SetLum(Cb, Lum(Cs));
}
const int MixBlendMode_Multiply = 1;
const int MixBlendMode_Screen = 2;
const int MixBlendMode_Overlay = 3;
const int MixBlendMode_Darken = 4;
const int MixBlendMode_Lighten = 5;
const int MixBlendMode_ColorDodge = 6;
const int MixBlendMode_ColorBurn = 7;
const int MixBlendMode_HardLight = 8;
const int MixBlendMode_SoftLight = 9;
const int MixBlendMode_Difference = 10;
const int MixBlendMode_Exclusion = 11;
const int MixBlendMode_Hue = 12;
const int MixBlendMode_Saturation = 13;
const int MixBlendMode_Color = 14;
const int MixBlendMode_Luminosity = 15;
void main(void) {
vec4 Cb = texture(sCache, vUv0);
vec4 Cs = texture(sCache, vUv1);
@ -159,60 +175,62 @@ void main(void) {
vec4 result = vec4(1.0, 1.0, 0.0, 1.0);
switch (vOp) {
case 1:
case MixBlendMode_Multiply:
result.rgb = Multiply(Cb.rgb, Cs.rgb);
break;
case 2:
case MixBlendMode_Screen:
result.rgb = Screen(Cb.rgb, Cs.rgb);
break;
case 3:
result.rgb = HardLight(Cs.rgb, Cb.rgb); // Overlay is inverse of Hardlight
case MixBlendMode_Overlay:
// Overlay is inverse of Hardlight
result.rgb = HardLight(Cs.rgb, Cb.rgb);
break;
case 4:
// mix-blend-mode: darken
case MixBlendMode_Darken:
result.rgb = min(Cs.rgb, Cb.rgb);
break;
case 5:
// mix-blend-mode: lighten
case MixBlendMode_Lighten:
result.rgb = max(Cs.rgb, Cb.rgb);
break;
case 6:
case MixBlendMode_ColorDodge:
result.r = ColorDodge(Cb.r, Cs.r);
result.g = ColorDodge(Cb.g, Cs.g);
result.b = ColorDodge(Cb.b, Cs.b);
break;
case 7:
case MixBlendMode_ColorBurn:
result.r = ColorBurn(Cb.r, Cs.r);
result.g = ColorBurn(Cb.g, Cs.g);
result.b = ColorBurn(Cb.b, Cs.b);
break;
case 8:
case MixBlendMode_HardLight:
result.rgb = HardLight(Cb.rgb, Cs.rgb);
break;
case 9:
case MixBlendMode_SoftLight:
result.r = SoftLight(Cb.r, Cs.r);
result.g = SoftLight(Cb.g, Cs.g);
result.b = SoftLight(Cb.b, Cs.b);
break;
case 10:
case MixBlendMode_Difference:
result.rgb = Difference(Cb.rgb, Cs.rgb);
break;
case 11:
case MixBlendMode_Exclusion:
result.rgb = Exclusion(Cb.rgb, Cs.rgb);
break;
case 12:
case MixBlendMode_Hue:
result.rgb = Hue(Cb.rgb, Cs.rgb);
break;
case 13:
case MixBlendMode_Saturation:
result.rgb = Saturation(Cb.rgb, Cs.rgb);
break;
case 14:
case MixBlendMode_Color:
result.rgb = Color(Cb.rgb, Cs.rgb);
break;
case 15:
case MixBlendMode_Luminosity:
result.rgb = Luminosity(Cb.rgb, Cs.rgb);
break;
}
result.rgb = (1.0 - Cb.a) * Cs.rgb + Cb.a * result.rgb;
result.a = Cs.a;
oFragColor = result;
}

Просмотреть файл

@ -19,8 +19,8 @@ void main(void) {
vec2 texture_size = vec2(textureSize(sCache, 0));
vec2 st0 = (backdrop_task.render_target_origin + vec2(0.0, backdrop_task.size.y)) / texture_size;
vec2 st1 = (backdrop_task.render_target_origin + vec2(backdrop_task.size.x, 0.0)) / texture_size;
vec2 st0 = backdrop_task.render_target_origin / texture_size;
vec2 st1 = (backdrop_task.render_target_origin + backdrop_task.size) / texture_size;
vUv0 = vec3(mix(st0, st1, aPosition.xy), backdrop_task.render_target_layer_index);
st0 = src_task.render_target_origin / texture_size;

Просмотреть файл

@ -12,25 +12,33 @@ void main(void) {
RectWithSize segment_rect;
vec2 axis;
vec4 adjusted_color_g0 = g0.color;
vec4 adjusted_color_g1 = g1.color;
if (gradient.start_end_point.y == gradient.start_end_point.w) {
float x0 = mix(gradient.start_end_point.x,
gradient.start_end_point.z,
g0.offset.x);
float x1 = mix(gradient.start_end_point.x,
gradient.start_end_point.z,
g1.offset.x);
segment_rect.p0 = vec2(x0, prim.local_rect.p0.y);
segment_rect.size = vec2(x1 - x0, prim.local_rect.size.y);
vec2 x = mix(gradient.start_end_point.xx, gradient.start_end_point.zz,
vec2(g0.offset.x, g1.offset.x));
// The start and end point of gradient might exceed the geometry rect. So clamp
// it to the geometry rect.
x = clamp(x, prim.local_rect.p0.xx, prim.local_rect.p0.xx + prim.local_rect.size.xx);
vec2 adjusted_offset =
(x - gradient.start_end_point.xx) / (gradient.start_end_point.zz - gradient.start_end_point.xx);
adjusted_color_g0 = mix(g0.color, g1.color, adjusted_offset.x);
adjusted_color_g1 = mix(g0.color, g1.color, adjusted_offset.y);
segment_rect.p0 = vec2(x.x, prim.local_rect.p0.y);
segment_rect.size = vec2(x.y - x.x, prim.local_rect.size.y);
axis = vec2(1.0, 0.0);
} else {
float y0 = mix(gradient.start_end_point.y,
gradient.start_end_point.w,
g0.offset.x);
float y1 = mix(gradient.start_end_point.y,
gradient.start_end_point.w,
g1.offset.x);
segment_rect.p0 = vec2(prim.local_rect.p0.x, y0);
segment_rect.size = vec2(prim.local_rect.size.x, y1 - y0);
vec2 y = mix(gradient.start_end_point.yy, gradient.start_end_point.ww,
vec2(g0.offset.x, g1.offset.x));
// The start and end point of gradient might exceed the geometry rect. So clamp
// it to the geometry rect.
y = clamp(y, prim.local_rect.p0.yy, prim.local_rect.p0.yy + prim.local_rect.size.yy);
vec2 adjusted_offset =
(y - gradient.start_end_point.yy) / (gradient.start_end_point.ww - gradient.start_end_point.yy);
adjusted_color_g0 = mix(g0.color, g1.color, adjusted_offset.x);
adjusted_color_g1 = mix(g0.color, g1.color, adjusted_offset.y);
segment_rect.p0 = vec2(prim.local_rect.p0.x, y.x);
segment_rect.size = vec2(prim.local_rect.size.x, y.y - y.x);
axis = vec2(0.0, 1.0);
}
@ -56,5 +64,5 @@ void main(void) {
write_clip(vi.screen_pos, prim.clip_area);
vColor = mix(g0.color, g1.color, dot(f, axis));
vColor = mix(adjusted_color_g0, adjusted_color_g1, dot(f, axis));
}

Просмотреть файл

@ -31,5 +31,5 @@ void main(void) {
alpha = alpha * float(all(bvec2(step(position_in_tile, vStretchSize))));
oFragColor = vec4(1.0, 1.0, 1.0, alpha) * textureLod(sColor0, st, 0.0);
oFragColor = vec4(alpha) * textureLod(sColor0, st, 0.0);
}

Просмотреть файл

@ -23,20 +23,23 @@ void main(void) {
#endif
YuvImage image = fetch_yuv_image(prim.prim_index);
ResourceRect y_rect = fetch_resource_rect(prim.user_data.x);
ResourceRect u_rect = fetch_resource_rect(prim.user_data.x + 1);
ResourceRect v_rect = fetch_resource_rect(prim.user_data.x + 2);
vec2 y_texture_size = vec2(textureSize(sColor0, 0));
vec2 y_st0 = image.y_st_rect.xy / y_texture_size;
vec2 y_st1 = image.y_st_rect.zw / y_texture_size;
vec2 y_st0 = y_rect.uv_rect.xy / y_texture_size;
vec2 y_st1 = y_rect.uv_rect.zw / y_texture_size;
vTextureSizeY = y_st1 - y_st0;
vTextureOffsetY = y_st0;
vec2 uv_texture_size = vec2(textureSize(sColor1, 0));
vec2 u_st0 = image.u_st_rect.xy / uv_texture_size;
vec2 u_st1 = image.u_st_rect.zw / uv_texture_size;
vec2 u_st0 = u_rect.uv_rect.xy / uv_texture_size;
vec2 u_st1 = u_rect.uv_rect.zw / uv_texture_size;
vec2 v_st0 = image.v_st_rect.xy / uv_texture_size;
vec2 v_st1 = image.v_st_rect.zw / uv_texture_size;
vec2 v_st0 = v_rect.uv_rect.xy / uv_texture_size;
vec2 v_st1 = v_rect.uv_rect.zw / uv_texture_size;
// This assumes the U and V surfaces have the same size.
vTextureSizeUv = u_st1 - u_st0;

Просмотреть файл

@ -4,11 +4,16 @@
use euclid::Point3D;
use geometry::ray_intersects_rect;
use mask_cache::{ClipSource, MaskCacheInfo};
use prim_store::GpuBlock32;
use renderer::VertexDataStore;
use spring::{DAMPING, STIFFNESS, Spring};
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform};
use webrender_traits::{LayerToWorldTransform, PipelineId, ScrollEventPhase, ScrollLayerId};
use webrender_traits::{ScrollLayerRect, ScrollLocation, ScrollToWorldTransform, WorldPoint};
use webrender_traits::{WorldPoint4D};
use tiling::PackedLayerIndex;
use util::TransformedRect;
use webrender_traits::{ClipRegion, LayerPixel, LayerPoint, LayerRect, LayerSize};
use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, PipelineId};
use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerRect, ScrollLocation};
use webrender_traits::{ServoScrollRootId, WorldPoint, WorldPoint4D};
#[cfg(target_os = "macos")]
const CAN_OVERSCROLL: bool = true;
@ -16,9 +21,67 @@ const CAN_OVERSCROLL: bool = true;
#[cfg(not(target_os = "macos"))]
const CAN_OVERSCROLL: bool = false;
#[derive(Clone, Debug)]
pub struct ClipInfo {
/// The ClipSource for this node, which is used to generate mask_cache_info.
pub clip_source: ClipSource,
/// The MaskCacheInfo for this node, which is produced by processing the
/// provided ClipSource.
pub mask_cache_info: Option<MaskCacheInfo>,
/// The packed layer index for this node, which is used to render a clip mask
/// for it, if necessary.
pub packed_layer_index: PackedLayerIndex,
/// The final transformed rectangle of this clipping region for this node,
/// which depends on the screen rectangle and the transformation of all of
/// the parents.
pub xf_rect: Option<TransformedRect>,
/// An external identifier that is used to scroll this clipping node
/// from the API.
pub scroll_root_id: Option<ServoScrollRootId>,
}
impl ClipInfo {
pub fn new(clip_region: &ClipRegion,
clip_store: &mut VertexDataStore<GpuBlock32>,
packed_layer_index: PackedLayerIndex,
scroll_root_id: Option<ServoScrollRootId>)
-> ClipInfo {
// We pass true here for the MaskCacheInfo because this type of
// mask needs an extra clip for the clip rectangle.
let clip_source = ClipSource::Region(clip_region.clone());
ClipInfo {
mask_cache_info: MaskCacheInfo::new(&clip_source, true, clip_store),
clip_source: clip_source,
packed_layer_index: packed_layer_index,
xf_rect: None,
scroll_root_id: scroll_root_id,
}
}
pub fn is_masking(&self) -> bool {
match self.mask_cache_info {
Some(ref info) => info.is_masking(),
_ => false,
}
}
}
#[derive(Clone, Debug)]
pub enum NodeType {
/// Transform for this layer, relative to parent reference frame. A reference
/// frame establishes a new coordinate space in the tree.
ReferenceFrame(LayerToScrollTransform),
/// Other nodes just do clipping, but no transformation.
Clip(ClipInfo),
}
/// Contains scrolling and transform information stacking contexts.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct ClipScrollNode {
/// Manages scrolling offset, overscroll state etc.
pub scrolling: ScrollingState,
@ -26,44 +89,78 @@ pub struct ClipScrollNode {
/// Size of the content inside the scroll region (in logical pixels)
pub content_size: LayerSize,
/// Viewing rectangle
/// Viewing rectangle in the coordinate system of the parent reference frame.
pub local_viewport_rect: LayerRect,
/// Viewing rectangle clipped against parent layer(s)
/// Clip rect of this node - typically the same as viewport rect, except
/// in overscroll cases.
pub local_clip_rect: LayerRect,
/// Viewport rectangle clipped against parent layer(s) viewport rectangles.
/// This is in the coordinate system of the parent reference frame.
pub combined_local_viewport_rect: LayerRect,
/// World transform for the viewport rect itself.
/// World transform for the viewport rect itself. This is the parent
/// reference frame transformation plus the scrolling offsets provided by
/// the nodes in between the reference frame and this node.
pub world_viewport_transform: LayerToWorldTransform,
/// World transform for content within this layer
/// World transform for content transformed by this node.
pub world_content_transform: LayerToWorldTransform,
/// Transform for this layer, relative to parent scrollable layer.
pub local_transform: LayerToScrollTransform,
/// Pipeline that this layer belongs to
pub pipeline_id: PipelineId,
/// Parent layer. If this is None, we are the root node.
pub parent: Option<ScrollLayerId>,
/// Child layers
pub children: Vec<ScrollLayerId>,
/// Whether or not this node is a reference frame.
pub node_type: NodeType,
}
impl ClipScrollNode {
pub fn new(local_viewport_rect: &LayerRect,
pub fn new(pipeline_id: PipelineId,
parent_id: ScrollLayerId,
local_viewport_rect: &LayerRect,
content_size: LayerSize,
local_transform: &LayerToScrollTransform,
pipeline_id: PipelineId)
clip_info: ClipInfo)
-> ClipScrollNode {
ClipScrollNode {
scrolling: ScrollingState::new(),
content_size: content_size,
local_viewport_rect: *local_viewport_rect,
combined_local_viewport_rect: *local_viewport_rect,
local_clip_rect: *local_viewport_rect,
combined_local_viewport_rect: LayerRect::zero(),
world_viewport_transform: LayerToWorldTransform::identity(),
world_content_transform: LayerToWorldTransform::identity(),
local_transform: *local_transform,
parent: Some(parent_id),
children: Vec::new(),
pipeline_id: pipeline_id,
node_type: NodeType::Clip(clip_info),
}
}
pub fn new_reference_frame(parent_id: Option<ScrollLayerId>,
local_viewport_rect: &LayerRect,
content_size: LayerSize,
local_transform: &LayerToScrollTransform,
pipeline_id: PipelineId)
-> ClipScrollNode {
ClipScrollNode {
scrolling: ScrollingState::new(),
content_size: content_size,
local_viewport_rect: *local_viewport_rect,
local_clip_rect: *local_viewport_rect,
combined_local_viewport_rect: LayerRect::zero(),
world_viewport_transform: LayerToWorldTransform::identity(),
world_content_transform: LayerToWorldTransform::identity(),
parent: parent_id,
children: Vec::new(),
pipeline_id: pipeline_id,
node_type: NodeType::ReferenceFrame(*local_transform),
}
}
@ -117,9 +214,16 @@ impl ClipScrollNode {
}
pub fn update_transform(&mut self,
parent_world_transform: &ScrollToWorldTransform,
parent_viewport_rect: &ScrollLayerRect) {
let inv_transform = match self.local_transform.inverse() {
parent_reference_frame_transform: &LayerToWorldTransform,
parent_combined_viewport_rect: &ScrollLayerRect,
parent_accumulated_scroll_offset: LayerPoint) {
let local_transform = match self.node_type {
NodeType::ReferenceFrame(transform) => transform,
NodeType::Clip(_) => LayerToScrollTransform::identity(),
};
let inv_transform = match local_transform.inverse() {
Some(transform) => transform,
None => {
// If a transform function causes the current transformation matrix of an object
@ -129,18 +233,40 @@ impl ClipScrollNode {
}
};
let parent_viewport_rect_in_local_space = inv_transform.transform_rect(parent_viewport_rect)
.translate(&-self.scrolling.offset);
let local_viewport_rect = self.local_viewport_rect.translate(&-self.scrolling.offset);
let viewport_rect = parent_viewport_rect_in_local_space.intersection(&local_viewport_rect)
.unwrap_or(LayerRect::zero());
// We are trying to move the combined viewport rectangle of our parent nodes into the
// coordinate system of this node, so we must invert our transformation (only for
// reference frames) and then apply the scroll offset of all the parent layers.
let parent_combined_viewport_in_local_space =
inv_transform.pre_translated(-parent_accumulated_scroll_offset.x,
-parent_accumulated_scroll_offset.y,
0.0)
.transform_rect(parent_combined_viewport_rect);
self.combined_local_viewport_rect = viewport_rect;
self.world_viewport_transform = parent_world_transform.pre_mul(&self.local_transform);
self.world_content_transform = self.world_viewport_transform
.pre_translated(self.scrolling.offset.x,
self.scrolling.offset.y,
0.0);
// Now that we have the combined viewport rectangle of the parent nodes in local space,
// we do the intersection and get our combined viewport rect in the coordinate system
// starting from our origin.
self.combined_local_viewport_rect =
parent_combined_viewport_in_local_space.intersection(&self.local_clip_rect)
.unwrap_or(LayerRect::zero());
// The transformation for this viewport in world coordinates is the transformation for
// our parent reference frame, plus any accumulated scrolling offsets from nodes
// between our reference frame and this node. For reference frames, we also include
// whatever local transformation this reference frame provides. This can be combined
// with the local_viewport_rect to get its position in world space.
self.world_viewport_transform =
parent_reference_frame_transform
.pre_translated(parent_accumulated_scroll_offset.x,
parent_accumulated_scroll_offset.y,
0.0)
.pre_mul(&local_transform.with_destination::<LayerPixel>());
// The transformation for any content inside of us is the viewport transformation, plus
// whatever scrolling offset we supply as well.
self.world_content_transform =
self.world_viewport_transform.pre_translated(self.scrolling.offset.x,
self.scrolling.offset.y,
0.0);
}
pub fn scrollable_height(&self) -> f32 {
@ -265,7 +391,7 @@ impl ClipScrollNode {
}
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct ScrollingState {
pub offset: LayerPoint,
pub spring: Spring,

Просмотреть файл

@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState};
use fnv::FnvHasher;
use clip_scroll_node::{ClipScrollNode, ScrollingState};
use std::collections::{HashMap, HashSet};
use std::hash::BuildHasherDefault;
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId};
use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerInfo, ScrollLayerPixel};
use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ScrollToWorldTransform};
use webrender_traits::{ServoScrollRootId, WorldPoint, as_scroll_parent_rect};
use webrender_traits::{LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform};
use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerInfo};
use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ServoScrollRootId};
use webrender_traits::{WorldPoint, as_scroll_parent_rect};
pub type ScrollStates = HashMap<ScrollLayerId, ScrollingState, BuildHasherDefault<FnvHasher>>;
@ -48,7 +48,7 @@ impl ClipScrollTree {
current_scroll_layer_id: None,
root_reference_frame_id: ScrollLayerId::root_reference_frame(dummy_pipeline),
topmost_scroll_layer_id: ScrollLayerId::root_scroll_layer(dummy_pipeline),
current_reference_frame_id: 1,
current_reference_frame_id: 0,
pipelines_to_discard: HashSet::new(),
}
}
@ -67,26 +67,6 @@ impl ClipScrollTree {
self.topmost_scroll_layer_id
}
pub fn establish_root(&mut self,
pipeline_id: PipelineId,
viewport_size: &LayerSize,
content_size: &LayerSize) {
debug_assert!(self.nodes.is_empty());
let identity = LayerToScrollTransform::identity();
let viewport = LayerRect::new(LayerPoint::zero(), *viewport_size);
let root_reference_frame_id = ScrollLayerId::root_reference_frame(pipeline_id);
self.root_reference_frame_id = root_reference_frame_id;
let reference_frame = ClipScrollNode::new(&viewport, viewport.size, &identity, pipeline_id);
self.nodes.insert(self.root_reference_frame_id, reference_frame);
let scroll_node = ClipScrollNode::new(&viewport, *content_size, &identity, pipeline_id);
let topmost_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id);
self.topmost_scroll_layer_id = topmost_scroll_layer_id;
self.add_node(scroll_node, topmost_scroll_layer_id, root_reference_frame_id);
}
pub fn collect_nodes_bouncing_back(&self)
-> HashSet<ScrollLayerId, BuildHasherDefault<FnvHasher>> {
let mut nodes_bouncing_back = HashSet::with_hasher(Default::default());
@ -129,16 +109,16 @@ impl ClipScrollTree {
pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
let mut result = vec![];
for (scroll_layer_id, scroll_node) in self.nodes.iter() {
match scroll_layer_id.info {
ScrollLayerInfo::Scrollable(_, servo_scroll_root_id) => {
for (_, node) in self.nodes.iter() {
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id.is_some() => {
result.push(ScrollLayerState {
pipeline_id: scroll_node.pipeline_id,
scroll_root_id: servo_scroll_root_id,
scroll_offset: scroll_node.scrolling.offset,
pipeline_id: node.pipeline_id,
scroll_root_id: info.scroll_root_id.unwrap(),
scroll_offset: node.scrolling.offset,
})
}
ScrollLayerInfo::ReferenceFrame(..) => {}
_ => {},
}
}
result
@ -177,10 +157,10 @@ impl ClipScrollTree {
continue;
}
match layer_id.info {
ScrollLayerInfo::Scrollable(_, id) if id != scroll_root_id => continue,
ScrollLayerInfo::ReferenceFrame(..) => continue,
ScrollLayerInfo::Scrollable(..) => {}
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id != Some(scroll_root_id) => continue,
NodeType::ReferenceFrame(..) => continue,
NodeType::Clip(_) => {},
}
found_node = true;
@ -258,16 +238,26 @@ impl ClipScrollTree {
},
};
let scroll_node_info = if switch_node {
topmost_scroll_layer_id.info
let scroll_layer_id = if switch_node {
topmost_scroll_layer_id
} else {
scroll_layer_id.info
scroll_layer_id
};
let scroll_root_id = match scroll_node_info {
ScrollLayerInfo::Scrollable(_, scroll_root_id) => scroll_root_id,
_ => unreachable!("Tried to scroll a reference frame."),
// TODO(mrobinson): Once we remove the concept of shared scroll root ids we can remove
// this entirely and just scroll the node based on the ScrollLayerId.
let scroll_root_id = {
let node = self.nodes.get_mut(&scroll_layer_id).unwrap();
let scroll_root_id = match node.node_type {
NodeType::Clip(ref info) => info.scroll_root_id,
NodeType::ReferenceFrame(..) => unreachable!("Tried to scroll a reference frame."),
};
if scroll_root_id.is_none() {
return node.scroll(scroll_location, phase);
}
scroll_root_id
};
let mut scrolled_a_node = false;
@ -276,10 +266,9 @@ impl ClipScrollTree {
continue;
}
match layer_id.info {
ScrollLayerInfo::Scrollable(_, id) if id != scroll_root_id => continue,
ScrollLayerInfo::ReferenceFrame(..) => continue,
_ => {}
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id == scroll_root_id => { }
_ => continue,
}
let scrolled_this_node = node.scroll(scroll_location, phase);
@ -288,31 +277,49 @@ impl ClipScrollTree {
scrolled_a_node
}
pub fn update_all_node_transforms(&mut self) {
pub fn update_all_node_transforms(&mut self, pan: LayerPoint) {
if self.nodes.is_empty() {
return;
}
let root_reference_frame_id = self.root_reference_frame_id();
let root_viewport = self.nodes[&root_reference_frame_id].local_viewport_rect;
let root_viewport = self.nodes[&root_reference_frame_id].local_clip_rect;
self.update_node_transform(root_reference_frame_id,
&ScrollToWorldTransform::identity(),
&as_scroll_parent_rect(&root_viewport));
&LayerToWorldTransform::create_translation(pan.x, pan.y, 0.0),
&as_scroll_parent_rect(&root_viewport),
LayerPoint::zero());
}
fn update_node_transform(&mut self,
layer_id: ScrollLayerId,
parent_world_transform: &ScrollToWorldTransform,
parent_viewport_rect: &ScrollLayerRect) {
parent_reference_frame_transform: &LayerToWorldTransform,
parent_viewport_rect: &ScrollLayerRect,
parent_accumulated_scroll_offset: LayerPoint) {
// TODO(gw): This is an ugly borrow check workaround to clone these.
// Restructure this to avoid the clones!
let (node_transform_for_children, viewport_rect, node_children) = {
let (reference_frame_transform, viewport_rect, accumulated_scroll_offset, node_children) = {
match self.nodes.get_mut(&layer_id) {
Some(node) => {
node.update_transform(parent_world_transform, parent_viewport_rect);
node.update_transform(parent_reference_frame_transform,
parent_viewport_rect,
parent_accumulated_scroll_offset);
(node.world_content_transform.with_source::<ScrollLayerPixel>(),
// The transformation we are passing is the transformation of the parent
// reference frame and the offset is the accumulated offset of all the nodes
// between us and the parent reference frame. If we are a reference frame,
// we need to reset both these values.
let (transform, offset) = match node.node_type {
NodeType::ReferenceFrame(..) =>
(node.world_viewport_transform, LayerPoint::zero()),
NodeType::Clip(_) => {
(*parent_reference_frame_transform,
parent_accumulated_scroll_offset + node.scrolling.offset)
}
};
(transform,
as_scroll_parent_rect(&node.combined_local_viewport_rect),
offset,
node.children.clone())
}
None => return,
@ -321,8 +328,9 @@ impl ClipScrollTree {
for child_layer_id in node_children {
self.update_node_transform(child_layer_id,
&node_transform_for_children,
&viewport_rect);
&reference_frame_transform,
&viewport_rect,
accumulated_scroll_offset);
}
}
@ -343,8 +351,9 @@ impl ClipScrollTree {
node.finalize(&scrolling_state);
let scroll_root_id = match scroll_layer_id.info {
ScrollLayerInfo::Scrollable(_, scroll_root_id) => scroll_root_id,
let scroll_root_id = match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id.is_some() =>
info.scroll_root_id.unwrap(),
_ => continue,
};
@ -359,27 +368,35 @@ impl ClipScrollTree {
}
pub fn add_reference_frame(&mut self,
rect: LayerRect,
transform: LayerToScrollTransform,
rect: &LayerRect,
transform: &LayerToScrollTransform,
pipeline_id: PipelineId,
parent_id: ScrollLayerId) -> ScrollLayerId {
parent_id: Option<ScrollLayerId>)
-> ScrollLayerId {
let reference_frame_id = ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::ReferenceFrame(self.current_reference_frame_id),
};
self.current_reference_frame_id += 1;
let node = ClipScrollNode::new(&rect, rect.size, &transform, pipeline_id);
self.add_node(node, reference_frame_id, parent_id);
let node = ClipScrollNode::new_reference_frame(parent_id,
&rect,
rect.size,
&transform,
pipeline_id);
self.add_node(node, reference_frame_id);
reference_frame_id
}
pub fn add_node(&mut self, node: ClipScrollNode, id: ScrollLayerId, parent_id: ScrollLayerId) {
pub fn add_node(&mut self, node: ClipScrollNode, id: ScrollLayerId) {
// When the parent node is None this means we are adding the root.
match node.parent {
Some(parent_id) => self.nodes.get_mut(&parent_id).unwrap().add_child(id),
None => self.root_reference_frame_id = id,
}
debug_assert!(!self.nodes.contains_key(&id));
self.nodes.insert(id, node);
debug_assert!(parent_id != id);
self.nodes.get_mut(&parent_id).unwrap().add_child(id);
}
pub fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) {

Просмотреть файл

@ -22,6 +22,9 @@ use std::path::PathBuf;
use webrender_traits::{ColorF, ImageFormat};
use webrender_traits::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintSize};
#[derive(Debug, Copy, Clone)]
pub struct FrameId(usize);
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
const GL_FORMAT_A: gl::GLuint = gl::RED;
@ -497,6 +500,7 @@ pub struct GpuFrameProfile<T> {
samples: Vec<GpuSample<T>>,
next_query: usize,
pending_query: gl::GLuint,
frame_id: FrameId,
}
impl<T> GpuFrameProfile<T> {
@ -509,6 +513,7 @@ impl<T> GpuFrameProfile<T> {
samples: Vec::new(),
next_query: 0,
pending_query: 0,
frame_id: FrameId(0),
}
}
@ -519,10 +524,12 @@ impl<T> GpuFrameProfile<T> {
samples: Vec::new(),
next_query: 0,
pending_query: 0,
frame_id: FrameId(0),
}
}
fn begin_frame(&mut self) {
fn begin_frame(&mut self, frame_id: FrameId) {
self.frame_id = frame_id;
self.next_query = 0;
self.pending_query = 0;
self.samples.clear();
@ -572,7 +579,7 @@ impl<T> GpuFrameProfile<T> {
}
fn is_valid(&self) -> bool {
self.next_query <= MAX_EVENTS_PER_FRAME
self.next_query > 0 && self.next_query <= MAX_EVENTS_PER_FRAME
}
#[cfg(not(target_os = "android"))]
@ -619,18 +626,18 @@ impl<T> GpuProfiler<T> {
}
}
pub fn build_samples(&mut self) -> Option<Vec<GpuSample<T>>> {
pub fn build_samples(&mut self) -> Option<(FrameId, Vec<GpuSample<T>>)> {
let frame = &mut self.frames[self.next_frame];
if frame.is_valid() {
Some(frame.build_samples())
Some((frame.frame_id, frame.build_samples()))
} else {
None
}
}
pub fn begin_frame(&mut self) {
pub fn begin_frame(&mut self, frame_id: FrameId) {
let frame = &mut self.frames[self.next_frame];
frame.begin_frame();
frame.begin_frame(frame_id);
}
pub fn end_frame(&mut self) {
@ -821,6 +828,10 @@ pub struct Device {
next_vao_id: gl::GLuint,
max_texture_size: u32,
// Frame counter. This is used to map between CPU
// frames and GPU frames.
frame_id: FrameId,
}
impl Device {
@ -860,7 +871,8 @@ impl Device {
next_vao_id: 1,
//file_watcher: file_watcher,
max_texture_size: gl::get_integer_v(gl::MAX_TEXTURE_SIZE) as u32
max_texture_size: gl::get_integer_v(gl::MAX_TEXTURE_SIZE) as u32,
frame_id: FrameId(0),
}
}
@ -903,7 +915,7 @@ impl Device {
}
}
pub fn begin_frame(&mut self, device_pixel_ratio: f32) {
pub fn begin_frame(&mut self, device_pixel_ratio: f32) -> FrameId {
debug_assert!(!self.inside_frame);
self.inside_frame = true;
self.device_pixel_ratio = device_pixel_ratio;
@ -938,6 +950,8 @@ impl Device {
// Default is sampler 0, always
gl::active_texture(gl::TEXTURE0);
self.frame_id
}
pub fn bind_texture(&mut self,
@ -1826,6 +1840,8 @@ impl Device {
}
gl::active_texture(gl::TEXTURE0);
self.frame_id.0 += 1;
}
pub fn assign_ubo_binding(&self, program_id: ProgramId, name: &str, value: u32) -> u32 {
@ -1886,6 +1902,30 @@ impl Device {
}
}
pub fn clear_target_rect(&self,
color: Option<[f32; 4]>,
depth: Option<f32>,
rect: DeviceIntRect) {
let mut clear_bits = 0;
if let Some(color) = color {
gl::clear_color(color[0], color[1], color[2], color[3]);
clear_bits |= gl::COLOR_BUFFER_BIT;
}
if let Some(depth) = depth {
gl::clear_depth(depth as f64);
clear_bits |= gl::DEPTH_BUFFER_BIT;
}
if clear_bits != 0 {
gl::enable(gl::SCISSOR_TEST);
gl::scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
gl::clear(clear_bits);
gl::disable(gl::SCISSOR_TEST);
}
}
pub fn enable_depth(&self) {
gl::enable(gl::DEPTH_TEST);
}
@ -1923,7 +1963,7 @@ impl Device {
}
pub fn set_blend_mode_premultiplied_alpha(&self) {
gl::blend_func(gl::SRC_ALPHA, gl::ZERO);
gl::blend_func(gl::ONE, gl::ONE_MINUS_SRC_ALPHA);
gl::blend_equation(gl::FUNC_ADD);
}

Просмотреть файл

@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use euclid::rect::rect;
use fnv::FnvHasher;
use internal_types::{ANGLE_FLOAT_TO_FIXED, AxisDirection};
use internal_types::{LowLevelFilterOp};
use internal_types::{RendererFrame};
use frame_builder::{FrameBuilder, FrameBuilderConfig};
use clip_scroll_node::ClipScrollNode;
use clip_scroll_tree::{ClipScrollTree, ScrollStates};
use profiler::TextureCacheProfileCounters;
use resource_cache::ResourceCache;
@ -16,11 +16,12 @@ use scene::{Scene, SceneProperties};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use tiling::{AuxiliaryListsMap, CompositeOps, PrimitiveFlags};
use webrender_traits::{AuxiliaryLists, ClipRegion, ColorF, DisplayItem, Epoch, FilterOp};
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform, TileOffset};
use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerState};
use webrender_traits::{ScrollLocation, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem};
use webrender_traits::{StackingContext, WorldPoint, ImageDisplayItem, DeviceUintSize};
use webrender_traits::{AuxiliaryLists, ClipDisplayItem, ClipRegion, ColorF, DeviceUintRect};
use webrender_traits::{DeviceUintSize, DisplayItem, Epoch, FilterOp, ImageDisplayItem, LayerPoint};
use webrender_traits::{LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform};
use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId};
use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, ServoScrollRootId};
use webrender_traits::{SpecificDisplayItem, StackingContext, TileOffset, WorldPoint};
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
pub struct FrameId(pub u32);
@ -31,6 +32,28 @@ struct FlattenContext<'a> {
scene: &'a Scene,
builder: &'a mut FrameBuilder,
resource_cache: &'a mut ResourceCache,
replacements: Vec<(ScrollLayerId, ScrollLayerId)>,
}
impl<'a> FlattenContext<'a> {
fn new(scene: &'a Scene,
builder: &'a mut FrameBuilder,
resource_cache: &'a mut ResourceCache)
-> FlattenContext<'a> {
FlattenContext {
scene: scene,
builder: builder,
resource_cache: resource_cache,
replacements: Vec::new(),
}
}
fn scroll_layer_id_with_replacement(&self, id: ScrollLayerId) -> ScrollLayerId {
match self.replacements.last() {
Some(&(to_replace, replacement)) if to_replace == id => replacement,
_ => id,
}
}
}
// TODO: doc
@ -141,10 +164,15 @@ impl<'a> DisplayListTraversal<'a> {
}
pub fn skip_current_stacking_context(&mut self) {
let mut depth = 0;
for item in self {
if item.item == SpecificDisplayItem::PopStackingContext {
return;
match item.item {
SpecificDisplayItem::PushStackingContext(..) => depth += 1,
SpecificDisplayItem::PopStackingContext if depth == 0 => return,
SpecificDisplayItem::PopStackingContext => depth -= 1,
_ => {}
}
debug_assert!(depth >= 0);
}
}
@ -228,7 +256,12 @@ impl Frame {
self.clip_scroll_tree.discard_frame_state_for_pipeline(pipeline_id);
}
pub fn create(&mut self, scene: &Scene, resource_cache: &mut ResourceCache) {
pub fn create(&mut self,
scene: &Scene,
resource_cache: &mut ResourceCache,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect,
device_pixel_ratio: f32) {
let root_pipeline_id = match scene.root_pipeline_id {
Some(root_pipeline_id) => root_pipeline_id,
None => return,
@ -245,6 +278,11 @@ impl Frame {
None => return,
};
if window_size.width == 0 || window_size.height == 0 {
println!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
return;
}
let old_scrolling_states = self.reset();
self.pipeline_auxiliary_lists = scene.pipeline_auxiliary_lists.clone();
@ -258,10 +296,6 @@ impl Frame {
}
};
self.clip_scroll_tree.establish_root(root_pipeline_id,
&root_pipeline.viewport_size,
&root_clip.main.size);
let background_color = root_pipeline.background_color.and_then(|color| {
if color.a > 0.0 {
Some(color)
@ -270,97 +304,63 @@ impl Frame {
}
});
let mut frame_builder = FrameBuilder::new(root_pipeline.viewport_size,
let mut frame_builder = FrameBuilder::new(window_size,
background_color,
self.frame_builder_config);
{
let mut context = FlattenContext {
scene: scene,
builder: &mut frame_builder,
resource_cache: resource_cache
};
let mut context = FlattenContext::new(scene, &mut frame_builder, resource_cache);
let scroll_layer_id = context.builder.push_root(root_pipeline_id,
&root_pipeline.viewport_size,
&root_clip.main.size,
&mut self.clip_scroll_tree);
context.builder.setup_viewport_offset(window_size,
inner_rect,
device_pixel_ratio,
&mut self.clip_scroll_tree);
let mut traversal = DisplayListTraversal::new_skipping_first(display_list);
let reference_frame_id = self.clip_scroll_tree.root_reference_frame_id();
let topmost_scroll_layer_id = self.clip_scroll_tree.topmost_scroll_layer_id();
debug_assert!(reference_frame_id != topmost_scroll_layer_id);
let viewport_rect = LayerRect::new(LayerPoint::zero(), root_pipeline.viewport_size);
let clip = ClipRegion::simple(&viewport_rect);
context.builder.push_clip_scroll_node(reference_frame_id,
&clip,
&LayerPoint::zero(),
&root_pipeline.viewport_size);
context.builder.push_clip_scroll_node(topmost_scroll_layer_id,
&clip,
&LayerPoint::zero(),
&root_clip.main.size);
self.flatten_stacking_context(&mut traversal,
root_pipeline_id,
&mut context,
reference_frame_id,
topmost_scroll_layer_id,
LayerToScrollTransform::identity(),
scroll_layer_id,
LayerPoint::zero(),
0,
&root_stacking_context,
root_clip);
context.builder.pop_clip_scroll_node();
context.builder.pop_clip_scroll_node();
}
self.frame_builder = Some(frame_builder);
self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
}
fn flatten_scroll_layer<'a>(&mut self,
traversal: &mut DisplayListTraversal<'a>,
pipeline_id: PipelineId,
context: &mut FlattenContext,
current_reference_frame_id: ScrollLayerId,
parent_scroll_layer_id: ScrollLayerId,
layer_relative_transform: LayerToScrollTransform,
level: i32,
clip: &ClipRegion,
content_size: &LayerSize,
new_scroll_layer_id: ScrollLayerId) {
// Avoid doing unnecessary work for empty stacking contexts.
if traversal.current_stacking_context_empty() {
traversal.skip_current_stacking_context();
return;
}
fn flatten_clip<'a>(&mut self,
context: &mut FlattenContext,
pipeline_id: PipelineId,
parent_id: ScrollLayerId,
item: &ClipDisplayItem,
reference_frame_relative_offset: LayerPoint,
clip: &ClipRegion) {
let clip_rect = clip.main.translate(&reference_frame_relative_offset);
context.builder.add_clip_scroll_node(item.id,
parent_id,
pipeline_id,
&clip_rect,
&item.content_size,
item.scroll_root_id,
clip,
&mut self.clip_scroll_tree);
let clip_rect = clip.main;
let node = ClipScrollNode::new(&clip_rect,
*content_size,
&layer_relative_transform,
pipeline_id);
self.clip_scroll_tree.add_node(node, new_scroll_layer_id, parent_scroll_layer_id);
context.builder.push_clip_scroll_node(new_scroll_layer_id,
clip,
&clip_rect.origin,
&content_size);
self.flatten_items(traversal,
pipeline_id,
context,
current_reference_frame_id,
new_scroll_layer_id,
LayerToScrollTransform::identity(),
level);
context.builder.pop_clip_scroll_node();
}
fn flatten_stacking_context<'a>(&mut self,
traversal: &mut DisplayListTraversal<'a>,
pipeline_id: PipelineId,
context: &mut FlattenContext,
current_reference_frame_id: ScrollLayerId,
current_scroll_layer_id: ScrollLayerId,
layer_relative_transform: LayerToScrollTransform,
context_scroll_layer_id: ScrollLayerId,
mut reference_frame_relative_offset: LayerPoint,
level: i32,
stacking_context: &StackingContext,
clip_region: &ClipRegion) {
@ -384,92 +384,102 @@ impl Frame {
return;
}
let stacking_context_transform = context.scene
.properties
.resolve_layout_transform(&stacking_context.transform);
let mut scroll_layer_id =
context.scroll_layer_id_with_replacement(context_scroll_layer_id);
let mut transform =
layer_relative_transform.pre_translated(stacking_context.bounds.origin.x,
stacking_context.bounds.origin.y,
0.0)
.pre_mul(&stacking_context_transform)
.pre_mul(&stacking_context.perspective);
let mut reference_frame_id = current_reference_frame_id;
let mut scroll_layer_id = match stacking_context.scroll_policy {
ScrollPolicy::Fixed => current_reference_frame_id,
ScrollPolicy::Scrollable => current_scroll_layer_id,
};
if stacking_context.scroll_policy == ScrollPolicy::Fixed {
context.replacements.push((context_scroll_layer_id,
context.builder.current_reference_frame_id()));
}
// If we have a transformation, we establish a new reference frame. This means
// that fixed position stacking contexts are positioned relative to us.
if stacking_context_transform != LayoutTransform::identity() ||
stacking_context.perspective != LayoutTransform::identity() {
scroll_layer_id = self.clip_scroll_tree.add_reference_frame(clip_region.main,
transform,
pipeline_id,
scroll_layer_id);
reference_frame_id = scroll_layer_id;
transform = LayerToScrollTransform::identity();
let is_reference_frame = stacking_context.transform.is_some() ||
stacking_context.perspective.is_some();
if is_reference_frame {
let transform = stacking_context.transform.as_ref();
let transform = context.scene.properties.resolve_layout_transform(transform);
let perspective =
stacking_context.perspective.unwrap_or_else(LayoutTransform::identity);
let transform =
LayerToScrollTransform::create_translation(reference_frame_relative_offset.x,
reference_frame_relative_offset.y,
0.0)
.pre_translated(stacking_context.bounds.origin.x,
stacking_context.bounds.origin.y,
0.0)
.pre_mul(&transform)
.pre_mul(&perspective);
scroll_layer_id = context.builder.push_reference_frame(Some(scroll_layer_id),
pipeline_id,
&clip_region.main,
&transform,
&mut self.clip_scroll_tree);
context.replacements.push((context_scroll_layer_id, scroll_layer_id));
reference_frame_relative_offset = LayerPoint::zero();
} else {
reference_frame_relative_offset = LayerPoint::new(
reference_frame_relative_offset.x + stacking_context.bounds.origin.x,
reference_frame_relative_offset.y + stacking_context.bounds.origin.y);
}
// TODO(gw): Int with overflow etc
context.builder.push_stacking_context(reference_frame_relative_offset,
clip_region.main,
pipeline_id,
level == 0,
composition_operations);
if level == 0 {
if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) {
if let Some(bg_color) = pipeline.background_color {
// Adding a dummy layer for this rectangle in order to disable clipping.
let no_clip = ClipRegion::simple(&clip_region.main);
context.builder.push_stacking_context(clip_region.main,
transform,
pipeline_id,
scroll_layer_id,
CompositeOps::empty());
//Note: we don't use the original clip region here,
// Note: we don't use the original clip region here,
// it's already processed by the node we just pushed.
context.builder.add_solid_rectangle(&clip_region.main,
&no_clip,
let background_rect = LayerRect::new(LayerPoint::zero(), clip_region.main.size);
context.builder.add_solid_rectangle(scroll_layer_id,
&clip_region.main,
&ClipRegion::simple(&background_rect),
&bg_color,
PrimitiveFlags::None);
context.builder.pop_stacking_context();
}
}
}
// TODO(gw): Int with overflow etc
context.builder.push_stacking_context(clip_region.main,
transform,
pipeline_id,
scroll_layer_id,
composition_operations);
self.flatten_items(traversal,
pipeline_id,
context,
reference_frame_id,
scroll_layer_id,
transform,
reference_frame_relative_offset,
level);
if level == 0 && self.frame_builder_config.enable_scrollbars {
let scrollbar_rect = LayerRect::new(LayerPoint::zero(), LayerSize::new(10.0, 70.0));
context.builder.add_solid_rectangle(
scroll_layer_id,
&scrollbar_rect,
&ClipRegion::simple(&scrollbar_rect),
&DEFAULT_SCROLLBAR_COLOR,
PrimitiveFlags::Scrollbar(self.clip_scroll_tree.topmost_scroll_layer_id(), 4.0));
}
if stacking_context.scroll_policy == ScrollPolicy::Fixed {
context.replacements.pop();
}
if is_reference_frame {
context.replacements.pop();
context.builder.pop_reference_frame();
}
context.builder.pop_stacking_context();
}
fn flatten_iframe<'a>(&mut self,
pipeline_id: PipelineId,
parent_id: ScrollLayerId,
bounds: &LayerRect,
context: &mut FlattenContext,
current_scroll_layer_id: ScrollLayerId,
layer_relative_transform: LayerToScrollTransform) {
reference_frame_relative_offset: LayerPoint) {
let pipeline = match context.scene.pipeline_map.get(&pipeline_id) {
Some(pipeline) => pipeline,
@ -493,61 +503,56 @@ impl Frame {
self.pipeline_epoch_map.insert(pipeline_id, pipeline.epoch);
let iframe_rect = LayerRect::new(LayerPoint::zero(), bounds.size);
let transform = layer_relative_transform.pre_translated(bounds.origin.x,
bounds.origin.y,
0.0);
let iframe_reference_frame_id =
self.clip_scroll_tree.add_reference_frame(iframe_rect,
transform,
pipeline_id,
current_scroll_layer_id);
let iframe_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id);
let node = ClipScrollNode::new(&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
iframe_clip.main.size,
&LayerToScrollTransform::identity(),
pipeline_id);
self.clip_scroll_tree.add_node(node.clone(),
iframe_scroll_layer_id,
iframe_reference_frame_id);
let transform = LayerToScrollTransform::create_translation(
reference_frame_relative_offset.x + bounds.origin.x,
reference_frame_relative_offset.y + bounds.origin.y,
0.0);
context.builder.push_clip_scroll_node(iframe_reference_frame_id,
iframe_clip,
&LayerPoint::zero(),
&iframe_rect.size);
context.builder.push_clip_scroll_node(iframe_scroll_layer_id,
iframe_clip,
&LayerPoint::zero(),
&iframe_clip.main.size);
let iframe_reference_frame_id =
context.builder.push_reference_frame(Some(parent_id),
pipeline_id,
&iframe_rect,
&transform,
&mut self.clip_scroll_tree);
let iframe_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id);
context.builder.add_clip_scroll_node(
iframe_scroll_layer_id,
iframe_reference_frame_id,
pipeline_id,
&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
&iframe_clip.main.size,
Some(ServoScrollRootId(0)),
iframe_clip,
&mut self.clip_scroll_tree);
let mut traversal = DisplayListTraversal::new_skipping_first(display_list);
self.flatten_stacking_context(&mut traversal,
pipeline_id,
context,
iframe_reference_frame_id,
iframe_scroll_layer_id,
LayerToScrollTransform::identity(),
LayerPoint::zero(),
0,
&iframe_stacking_context,
iframe_clip);
context.builder.pop_clip_scroll_node();
context.builder.pop_clip_scroll_node();
context.builder.pop_reference_frame();
}
fn flatten_items<'a>(&mut self,
traversal: &mut DisplayListTraversal<'a>,
pipeline_id: PipelineId,
context: &mut FlattenContext,
current_reference_frame_id: ScrollLayerId,
current_scroll_layer_id: ScrollLayerId,
layer_relative_transform: LayerToScrollTransform,
reference_frame_relative_offset: LayerPoint,
level: i32) {
while let Some(item) = traversal.next() {
let scroll_layer_id = context.scroll_layer_id_with_replacement(item.scroll_layer_id);
match item.item {
SpecificDisplayItem::WebGL(ref info) => {
context.builder.add_webgl_rectangle(item.rect,
&item.clip, info.context_id);
context.builder.add_webgl_rectangle(scroll_layer_id,
item.rect,
&item.clip,
info.context_id);
}
SpecificDisplayItem::Image(ref info) => {
let image = context.resource_cache.get_image_properties(info.image_key);
@ -555,9 +560,16 @@ impl Frame {
// The image resource is tiled. We have to generate an image primitive
// for each tile.
let image_size = DeviceUintSize::new(image.descriptor.width, image.descriptor.height);
self.decompose_tiled_image(context, &item, info, image_size, tile_size as u32);
self.decompose_image(scroll_layer_id,
context,
&item.rect,
&item.clip,
info,
image_size,
tile_size as u32);
} else {
context.builder.add_image(item.rect,
context.builder.add_image(scroll_layer_id,
item.rect,
&item.clip,
&info.stretch_size,
&info.tile_spacing,
@ -568,7 +580,8 @@ impl Frame {
}
}
SpecificDisplayItem::YuvImage(ref info) => {
context.builder.add_yuv_image(item.rect,
context.builder.add_yuv_image(scroll_layer_id,
item.rect,
&item.clip,
info.y_image_key,
info.u_image_key,
@ -576,7 +589,8 @@ impl Frame {
info.color_space);
}
SpecificDisplayItem::Text(ref text_info) => {
context.builder.add_text(item.rect,
context.builder.add_text(scroll_layer_id,
item.rect,
&item.clip,
text_info.font_key,
text_info.size,
@ -586,31 +600,35 @@ impl Frame {
text_info.glyph_options);
}
SpecificDisplayItem::Rectangle(ref info) => {
context.builder.add_solid_rectangle(&item.rect,
context.builder.add_solid_rectangle(scroll_layer_id,
&item.rect,
&item.clip,
&info.color,
PrimitiveFlags::None);
}
SpecificDisplayItem::Gradient(ref info) => {
context.builder.add_gradient(item.rect,
context.builder.add_gradient(scroll_layer_id,
item.rect,
&item.clip,
info.start_point,
info.end_point,
info.stops,
info.extend_mode);
info.gradient.start_point,
info.gradient.end_point,
info.gradient.stops,
info.gradient.extend_mode);
}
SpecificDisplayItem::RadialGradient(ref info) => {
context.builder.add_radial_gradient(item.rect,
context.builder.add_radial_gradient(scroll_layer_id,
item.rect,
&item.clip,
info.start_center,
info.start_radius,
info.end_center,
info.end_radius,
info.stops,
info.extend_mode);
info.gradient.start_center,
info.gradient.start_radius,
info.gradient.end_center,
info.gradient.end_radius,
info.gradient.stops,
info.gradient.extend_mode);
}
SpecificDisplayItem::BoxShadow(ref box_shadow_info) => {
context.builder.add_box_shadow(&box_shadow_info.box_bounds,
context.builder.add_box_shadow(scroll_layer_id,
&box_shadow_info.box_bounds,
&item.clip,
&box_shadow_info.offset,
&box_shadow_info.color,
@ -620,47 +638,117 @@ impl Frame {
box_shadow_info.clip_mode);
}
SpecificDisplayItem::Border(ref info) => {
context.builder.add_border(item.rect, &item.clip, info);
context.builder.add_border(scroll_layer_id,
item.rect,
&item.clip,
info);
}
SpecificDisplayItem::PushStackingContext(ref info) => {
self.flatten_stacking_context(traversal,
pipeline_id,
context,
current_reference_frame_id,
current_scroll_layer_id,
layer_relative_transform,
item.scroll_layer_id,
reference_frame_relative_offset,
level + 1,
&info.stacking_context,
&item.clip);
}
SpecificDisplayItem::PushScrollLayer(ref info) => {
self.flatten_scroll_layer(traversal,
pipeline_id,
context,
current_reference_frame_id,
current_scroll_layer_id,
layer_relative_transform,
level,
&item.clip,
&info.content_size,
info.id);
}
SpecificDisplayItem::Iframe(ref info) => {
self.flatten_iframe(info.pipeline_id,
scroll_layer_id,
&item.rect,
context,
current_scroll_layer_id,
layer_relative_transform);
reference_frame_relative_offset);
}
SpecificDisplayItem::PopStackingContext |
SpecificDisplayItem::PopScrollLayer => return,
SpecificDisplayItem::Clip(ref info) => {
self.flatten_clip(context,
pipeline_id,
scroll_layer_id,
&info,
reference_frame_relative_offset,
&item.clip);
}
SpecificDisplayItem::PopStackingContext => return,
}
}
}
/// Decomposes an image display item that is repeated into an image per individual repetition.
/// We need to do this when we are unable to perform the repetition in the shader,
/// for example if the image is tiled.
///
/// In all of the "decompose" methods below, we independently handle horizontal and vertical
/// decomposition. This lets us generate the minimum amount of primitives by, for example,
/// decompositing the repetition horizontally while repeating vertically in the shader (for
/// an image where the width is too bug but the height is not).
///
/// decompose_image and decompose_image_row handle image repetitions while decompose_tiled_image
/// takes care of the decomposition required by the internal tiling of the image.
fn decompose_image(&mut self,
scroll_layer_id: ScrollLayerId,
context: &mut FlattenContext,
item_rect: &LayerRect,
item_clip: &ClipRegion,
info: &ImageDisplayItem,
image_size: DeviceUintSize,
tile_size: u32) {
let no_vertical_tiling = image_size.height <= tile_size;
let no_vertical_spacing = info.tile_spacing.height == 0.0;
if no_vertical_tiling && no_vertical_spacing {
self.decompose_image_row(scroll_layer_id, context, item_rect, item_clip, info, image_size, tile_size);
return;
}
// Decompose each vertical repetition into rows.
let layout_stride = info.stretch_size.height + info.tile_spacing.height;
let num_repetitions = (item_rect.size.height / layout_stride).ceil() as u32;
for i in 0..num_repetitions {
if let Some(row_rect) = rect(
item_rect.origin.x,
item_rect.origin.y + (i as f32) * layout_stride,
item_rect.size.width,
info.stretch_size.height
).intersection(&item_rect) {
self.decompose_image_row(scroll_layer_id, context, &row_rect, item_clip, info, image_size, tile_size);
}
}
}
fn decompose_image_row(&mut self,
scroll_layer_id: ScrollLayerId,
context: &mut FlattenContext,
item_rect: &LayerRect,
item_clip: &ClipRegion,
info: &ImageDisplayItem,
image_size: DeviceUintSize,
tile_size: u32) {
let no_horizontal_tiling = image_size.width <= tile_size;
let no_horizontal_spacing = info.tile_spacing.width == 0.0;
if no_horizontal_tiling && no_horizontal_spacing {
self.decompose_tiled_image(scroll_layer_id, context, item_rect, item_clip, info, image_size, tile_size);
return;
}
// Decompose each horizontal repetition.
let layout_stride = info.stretch_size.width + info.tile_spacing.width;
let num_repetitions = (item_rect.size.width / layout_stride).ceil() as u32;
for i in 0..num_repetitions {
if let Some(decomposed_rect) = rect(
item_rect.origin.x + (i as f32) * layout_stride,
item_rect.origin.y,
info.stretch_size.width,
item_rect.size.height,
).intersection(&item_rect) {
self.decompose_tiled_image(scroll_layer_id, context, &decomposed_rect, item_clip, info, image_size, tile_size);
}
}
}
fn decompose_tiled_image(&mut self,
scroll_layer_id: ScrollLayerId,
context: &mut FlattenContext,
item: &DisplayItem,
item_rect: &LayerRect,
item_clip: &ClipRegion,
info: &ImageDisplayItem,
image_size: DeviceUintSize,
tile_size: u32) {
@ -688,11 +776,6 @@ impl Frame {
// each generated image primitive corresponds to a tile in the texture cache, with the
// assumption that the smaller tiles with leftover sizes are sized to fit their own
// irregular size in the texture cache.
// TODO(nical) supporting tiled repeated images isn't implemented yet.
// One way to implement this is to have another level of decomposition on top of this one,
// and generate a set of image primitive per repetition just like we have a primitive
// per tile here.
//
// For the case where we don't tile along an axis, we can still perform the repetition in
// the shader (for this particular axis), and it is worth special-casing for this to avoid
@ -700,29 +783,21 @@ impl Frame {
// This can happen with very tall and thin images used as a repeating background.
// Apparently web authors do that...
let mut stretch_size = info.stretch_size;
let mut repeat_x = false;
let mut repeat_y = false;
if stretch_size.width < item.rect.size.width {
if image_size.width < tile_size {
// we don't actually tile in this dimmension so repeating can be done in the shader.
repeat_x = true;
} else {
println!("Unimplemented! repeating a tiled image (x axis)");
stretch_size.width = item.rect.size.width;
}
if info.stretch_size.width < item_rect.size.width {
// If this assert blows up it means we haven't properly decomposed the image in decompose_image_row.
debug_assert!(image_size.width <= tile_size);
// we don't actually tile in this dimmension so repeating can be done in the shader.
repeat_x = true;
}
if stretch_size.height < item.rect.size.height {
// we don't actually tile in this dimmension so repeating can be done in the shader.
if image_size.height < tile_size {
repeat_y = true;
} else {
println!("Unimplemented! repeating a tiled image (y axis)");
stretch_size.height = item.rect.size.height;
}
if info.stretch_size.height < item_rect.size.height {
// If this assert blows up it means we haven't properly decomposed the image in decompose_image.
debug_assert!(image_size.height <= tile_size);
// we don't actually tile in this dimmension so repeating can be done in the shader.
repeat_y = true;
}
let tile_size_f32 = tile_size as f32;
@ -738,8 +813,8 @@ impl Frame {
// Strected size of the tile in layout space.
let stretched_tile_size = LayerSize::new(
img_dw * stretch_size.width,
img_dh * stretch_size.height
img_dw * info.stretch_size.width,
img_dh * info.stretch_size.height
);
// The size in pixels of the tiles on the right and bottom edges, smaller
@ -749,7 +824,11 @@ impl Frame {
for ty in 0..num_tiles_y {
for tx in 0..num_tiles_x {
self.add_tile_primitive(context, item, info,
self.add_tile_primitive(scroll_layer_id,
context,
item_rect,
item_clip,
info,
TileOffset::new(tx, ty),
stretched_tile_size,
1.0, 1.0,
@ -757,7 +836,11 @@ impl Frame {
}
if leftover.width != 0 {
// Tiles on the right edge that are smaller than the tile size.
self.add_tile_primitive(context, item, info,
self.add_tile_primitive(scroll_layer_id,
context,
item_rect,
item_clip,
info,
TileOffset::new(num_tiles_x, ty),
stretched_tile_size,
(leftover.width as f32) / tile_size_f32,
@ -769,29 +852,41 @@ impl Frame {
if leftover.height != 0 {
for tx in 0..num_tiles_x {
// Tiles on the bottom edge that are smaller than the tile size.
self.add_tile_primitive(context, item, info,
self.add_tile_primitive(scroll_layer_id,
context,
item_rect,
item_clip,
info,
TileOffset::new(tx, num_tiles_y),
stretched_tile_size,
1.0,
(leftover.height as f32) / tile_size_f32,
repeat_x, repeat_y);
repeat_x,
repeat_y);
}
if leftover.width != 0 {
// Finally, the bottom-right tile with a "leftover" size.
self.add_tile_primitive(context, item, info,
self.add_tile_primitive(scroll_layer_id,
context,
item_rect,
item_clip,
info,
TileOffset::new(num_tiles_x, num_tiles_y),
stretched_tile_size,
(leftover.width as f32) / tile_size_f32,
(leftover.height as f32) / tile_size_f32,
repeat_x, repeat_y);
repeat_x,
repeat_y);
}
}
}
fn add_tile_primitive(&mut self,
scroll_layer_id: ScrollLayerId,
context: &mut FlattenContext,
item: &DisplayItem,
item_rect: &LayerRect,
item_clip: &ClipRegion,
info: &ImageDisplayItem,
tile_offset: TileOffset,
stretched_tile_size: LayerSize,
@ -814,7 +909,7 @@ impl Frame {
);
let mut prim_rect = LayerRect::new(
item.rect.origin + LayerPoint::new(
item_rect.origin + LayerPoint::new(
tile_offset.x as f32 * stretched_tile_size.width,
tile_offset.y as f32 * stretched_tile_size.height,
),
@ -823,18 +918,19 @@ impl Frame {
if repeat_x {
assert_eq!(tile_offset.x, 0);
prim_rect.size.width = item.rect.size.width;
prim_rect.size.width = item_rect.size.width;
}
if repeat_y {
assert_eq!(tile_offset.y, 0);
prim_rect.size.height = item.rect.size.height;
prim_rect.size.height = item_rect.size.height;
}
// Fix up the primitive's rect if it overflows the original item rect.
if let Some(prim_rect) = prim_rect.intersection(&item.rect) {
context.builder.add_image(prim_rect,
&item.clip,
if let Some(prim_rect) = prim_rect.intersection(&item_rect) {
context.builder.add_image(scroll_layer_id,
prim_rect,
&item_clip,
&stretched_size,
&info.tile_spacing,
None,
@ -848,9 +944,10 @@ impl Frame {
resource_cache: &mut ResourceCache,
auxiliary_lists_map: &AuxiliaryListsMap,
device_pixel_ratio: f32,
pan: LayerPoint,
texture_cache_profile: &mut TextureCacheProfileCounters)
-> RendererFrame {
self.clip_scroll_tree.update_all_node_transforms();
self.clip_scroll_tree.update_all_node_transforms(pan);
let frame = self.build_frame(resource_cache,
auxiliary_lists_map,
device_pixel_ratio,
@ -869,7 +966,7 @@ impl Frame {
let frame = frame_builder.as_mut().map(|builder|
builder.build(resource_cache,
self.id,
&self.clip_scroll_tree,
&mut self.clip_scroll_tree,
auxiliary_lists_map,
device_pixel_ratio,
texture_cache_profile)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,11 +5,21 @@
use device::TextureFilter;
use std::marker::PhantomData;
use std::mem;
use std::ops::Add;
use webrender_traits::ImageFormat;
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
pub struct GpuStoreAddress(pub i32);
impl Add<i32> for GpuStoreAddress {
type Output = GpuStoreAddress;
fn add(self, other: i32) -> GpuStoreAddress {
GpuStoreAddress(self.0 + other)
}
}
pub trait GpuStoreLayout {
fn image_format() -> ImageFormat;

Просмотреть файл

@ -20,7 +20,7 @@ use std::sync::Arc;
use tiling;
use renderer::BlendMode;
use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize};
use webrender_traits::{ImageFormat, NativeFontHandle, MixBlendMode};
use webrender_traits::{ImageFormat, NativeFontHandle};
use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand};
use webrender_traits::{ImageData};
use webrender_traits::{DeviceUintRect};
@ -492,26 +492,13 @@ pub enum LowLevelFilterOp {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum HardwareCompositeOp {
Multiply,
Max,
Min,
Alpha,
}
impl HardwareCompositeOp {
pub fn from_mix_blend_mode(mix_blend_mode: MixBlendMode) -> Option<HardwareCompositeOp> {
match mix_blend_mode {
MixBlendMode::Multiply => Some(HardwareCompositeOp::Multiply),
MixBlendMode::Lighten => Some(HardwareCompositeOp::Max),
MixBlendMode::Darken => Some(HardwareCompositeOp::Min),
_ => None,
}
}
pub fn to_blend_mode(&self) -> BlendMode {
match self {
&HardwareCompositeOp::Multiply => BlendMode::Multiply,
&HardwareCompositeOp::Max => BlendMode::Max,
&HardwareCompositeOp::Min => BlendMode::Min,
&HardwareCompositeOp::Alpha => BlendMode::Alpha,
}
}
}

Просмотреть файл

@ -147,6 +147,20 @@ impl FontContext {
self.cg_fonts.insert((*font_key).clone(), native_font_handle);
}
pub fn delete_font(&mut self, font_key: &FontKey) {
if let Some(cg_font) = self.cg_fonts.remove(font_key) {
// Unstable Rust has a retain() method on HashMap that will
// let us do this in-place. https://github.com/rust-lang/rust/issues/36648
let ct_font_keys = self.ct_fonts.keys()
.filter(|k| k.0 == *font_key)
.cloned()
.collect::<Vec<_>>();
for ct_font_key in ct_font_keys {
self.ct_fonts.remove(&ct_font_key);
}
}
}
fn get_ct_font(&mut self,
font_key: FontKey,
size: Au) -> Option<CTFont> {

Просмотреть файл

@ -13,6 +13,7 @@ use freetype::freetype::{FT_Library, FT_Set_Char_Size};
use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6};
use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph};
use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter};
use freetype::freetype::{FT_Done_Face};
use std::{mem, ptr, slice};
use std::collections::HashMap;
@ -88,6 +89,15 @@ impl FontContext {
panic!("TODO: Not supported on Linux");
}
pub fn delete_font(&mut self, font_key: &FontKey) {
if let Some(face) = self.faces.remove(font_key) {
let result = unsafe {
FT_Done_Face(face.face)
};
assert!(result.succeeded());
}
}
fn load_glyph(&self,
font_key: FontKey,
size: Au,

Просмотреть файл

@ -143,6 +143,10 @@ impl FontContext {
self.fonts.insert((*font_key).clone(), face);
}
pub fn delete_font(&mut self, font_key: &FontKey) {
self.fonts.remove(font_key);
}
// Assumes RGB format from dwrite, which is 3 bytes per pixel as dwrite
// doesn't output an alpha value via GlyphRunAnalysis::CreateAlphaTexture
#[allow(dead_code)]
@ -230,13 +234,8 @@ impl FontContext {
let length = pixels.len() / 3;
let mut rgba_pixels: Vec<u8> = vec![0; length * 4];
for i in 0..length {
// TODO(vlad): we likely need to do something smarter
// This is what skia does
let alpha = ((pixels[i*3+0] as u32 +
pixels[i*3+1] as u32 +
pixels[i*3+2] as u32)
/ 3) as u8;
// Only take the G channel, as its closest to D2D
let alpha = pixels[i*3 + 1] as u8;
rgba_pixels[i*4+0] = alpha;
rgba_pixels[i*4+1] = alpha;
rgba_pixels[i*4+2] = alpha;
@ -278,22 +277,24 @@ impl FontContext {
let mut pixels = analysis.create_alpha_texture(texture_type, bounds);
let lut_correction = match glyph_options {
Some(option) => {
if option.force_gdi_rendering {
&self.gdi_gamma_lut
} else {
&self.gamma_lut
}
},
None => &self.gamma_lut
};
if render_mode != FontRenderMode::Mono {
let lut_correction = match glyph_options {
Some(option) => {
if option.force_gdi_rendering {
&self.gdi_gamma_lut
} else {
&self.gamma_lut
}
},
None => &self.gamma_lut
};
lut_correction.preblend_rgb(&mut pixels, width, height,
ColorLut::new(key.color.r,
key.color.g,
key.color.b,
key.color.a));
lut_correction.preblend_rgb(&mut pixels, width, height,
ColorLut::new(key.color.r,
key.color.g,
key.color.b,
key.color.a));
}
let rgba_pixels = self.convert_to_rgba(&mut pixels, render_mode);

Просмотреть файл

@ -9,7 +9,7 @@ use internal_types::{SourceTexture, PackedTexel};
use mask_cache::{ClipSource, MaskCacheInfo};
use renderer::{VertexDataStore, GradientDataStore};
use render_task::{RenderTask, RenderTaskLocation};
use resource_cache::{ImageProperties, ResourceCache};
use resource_cache::{CacheItem, ImageProperties, ResourceCache};
use std::mem;
use std::usize;
use util::TransformedRect;
@ -157,23 +157,17 @@ pub struct ImagePrimitiveGpu {
#[derive(Debug)]
pub struct YuvImagePrimitiveCpu {
pub y_key: ImageKey,
pub u_key: ImageKey,
pub v_key: ImageKey,
pub y_texture_id: SourceTexture,
pub u_texture_id: SourceTexture,
pub v_texture_id: SourceTexture,
pub yuv_key: [ImageKey; 3],
pub yuv_texture_id: [SourceTexture; 3],
// The first address of yuv resource_address. Use "yuv_resource_address + N-th" to get the N-th channel data.
// e.g. yuv_resource_address + 0 => y channel resource_address
pub yuv_resource_address: GpuStoreAddress,
}
#[derive(Debug, Clone)]
#[repr(C)]
pub struct YuvImagePrimitiveGpu {
pub y_uv0: DevicePoint,
pub y_uv1: DevicePoint,
pub u_uv0: DevicePoint,
pub u_uv1: DevicePoint,
pub v_uv0: DevicePoint,
pub v_uv1: DevicePoint,
pub size: LayerSize,
pub color_space: f32,
pub padding: f32,
@ -182,12 +176,6 @@ pub struct YuvImagePrimitiveGpu {
impl YuvImagePrimitiveGpu {
pub fn new(size: LayerSize, color_space: YuvColorSpace) -> Self {
YuvImagePrimitiveGpu {
y_uv0: DevicePoint::zero(),
y_uv1: DevicePoint::zero(),
u_uv0: DevicePoint::zero(),
u_uv1: DevicePoint::zero(),
v_uv0: DevicePoint::zero(),
v_uv1: DevicePoint::zero(),
size: size,
color_space: color_space as u32 as f32,
padding: 0.0,
@ -676,8 +664,10 @@ impl PrimitiveStore {
self.cpu_images.push(image_cpu);
metadata
}
PrimitiveContainer::YuvImage(image_cpu, image_gpu) => {
let gpu_address = self.gpu_data64.push(image_gpu);
PrimitiveContainer::YuvImage(mut image_cpu, image_gpu) => {
image_cpu.yuv_resource_address = self.gpu_resource_rects.alloc(3);
let gpu_address = self.gpu_data16.push(image_gpu);
let metadata = PrimitiveMetadata {
is_opaque: true,
@ -855,6 +845,35 @@ impl PrimitiveStore {
Self::resolve_clip_cache_internal(&mut self.gpu_data32, clip_info, resource_cache)
}
fn resolve_image(resource_cache: &ResourceCache,
deferred_resolves: &mut Vec<DeferredResolve>,
image_key: ImageKey,
image_uv_address: GpuStoreAddress,
image_rendering: ImageRendering,
tile_offset: Option<TileOffset>) -> (SourceTexture, Option<CacheItem>) {
let image_properties = resource_cache.get_image_properties(image_key);
// Check if an external image that needs to be resolved
// by the render thread.
match image_properties.external_id {
Some(external_id) => {
// This is an external texture - we will add it to
// the deferred resolves list to be patched by
// the render thread...
deferred_resolves.push(DeferredResolve {
image_properties: image_properties,
resource_address: image_uv_address,
});
(SourceTexture::External(external_id), None)
}
None => {
let cache_item = resource_cache.get_cached_image(image_key, image_rendering, tile_offset);
(cache_item.texture_id, Some(cache_item))
}
}
}
pub fn resolve_primitives(&mut self,
resource_cache: &ResourceCache,
device_pixel_ratio: f32) -> Vec<DeferredResolve> {
@ -902,25 +921,12 @@ impl PrimitiveStore {
ImagePrimitiveKind::Image(image_key, image_rendering, tile_offset, _) => {
// Check if an external image that needs to be resolved
// by the render thread.
let image_properties = resource_cache.get_image_properties(image_key);
match image_properties.external_id {
Some(external_id) => {
// This is an external texture - we will add it to
// the deferred resolves list to be patched by
// the render thread...
deferred_resolves.push(DeferredResolve {
resource_address: image_cpu.resource_address,
image_properties: image_properties,
});
(SourceTexture::External(external_id), None)
}
None => {
let cache_item = resource_cache.get_cached_image(image_key, image_rendering, tile_offset);
(cache_item.texture_id, Some(cache_item))
}
}
PrimitiveStore::resolve_image(resource_cache,
&mut deferred_resolves,
image_key,
image_cpu.resource_address,
image_rendering,
tile_offset)
}
ImagePrimitiveKind::WebGL(context_id) => {
let cache_item = resource_cache.get_webgl_texture(&context_id);
@ -947,29 +953,30 @@ impl PrimitiveStore {
}
PrimitiveKind::YuvImage => {
let image_cpu = &mut self.cpu_yuv_images[metadata.cpu_prim_index.0];
let image_gpu: &mut YuvImagePrimitiveGpu = unsafe {
mem::transmute(self.gpu_data64.get_mut(metadata.gpu_prim_index))
};
if image_cpu.y_texture_id == SourceTexture::Invalid {
let y_cache_item = resource_cache.get_cached_image(image_cpu.y_key, ImageRendering::Auto, None);
image_cpu.y_texture_id = y_cache_item.texture_id;
image_gpu.y_uv0 = y_cache_item.uv0;
image_gpu.y_uv1 = y_cache_item.uv1;
}
//yuv
for channel in 0..3 {
if image_cpu.yuv_texture_id[channel] == SourceTexture::Invalid {
// Check if an external image that needs to be resolved
// by the render thread.
let resource_address = image_cpu.yuv_resource_address + channel as i32;
if image_cpu.u_texture_id == SourceTexture::Invalid {
let u_cache_item = resource_cache.get_cached_image(image_cpu.u_key, ImageRendering::Auto, None);
image_cpu.u_texture_id = u_cache_item.texture_id;
image_gpu.u_uv0 = u_cache_item.uv0;
image_gpu.u_uv1 = u_cache_item.uv1;
}
if image_cpu.v_texture_id == SourceTexture::Invalid {
let v_cache_item = resource_cache.get_cached_image(image_cpu.v_key, ImageRendering::Auto, None);
image_cpu.v_texture_id = v_cache_item.texture_id;
image_gpu.v_uv0 = v_cache_item.uv0;
image_gpu.v_uv1 = v_cache_item.uv1;
let (texture_id, cache_item) =
PrimitiveStore::resolve_image(resource_cache,
&mut deferred_resolves,
image_cpu.yuv_key[channel],
resource_address,
ImageRendering::Auto,
None);
// texture_id
image_cpu.yuv_texture_id[channel] = texture_id;
// uv coordinates
if let Some(cache_item) = cache_item {
let resource_rect = self.gpu_resource_rects.get_mut(image_cpu.yuv_resource_address + channel as i32);
resource_rect.uv0 = cache_item.uv0;
resource_rect.uv1 = cache_item.uv1;
}
}
}
}
}
@ -1188,9 +1195,9 @@ impl PrimitiveStore {
let image_cpu = &mut self.cpu_yuv_images[metadata.cpu_prim_index.0];
prim_needs_resolve = true;
resource_cache.request_image(image_cpu.y_key, ImageRendering::Auto, None);
resource_cache.request_image(image_cpu.u_key, ImageRendering::Auto, None);
resource_cache.request_image(image_cpu.v_key, ImageRendering::Auto, None);
for channel in 0..3 {
resource_cache.request_image(image_cpu.yuv_key[channel], ImageRendering::Auto, None);
}
// TODO(nical): Currently assuming no tile_spacing for yuv images.
metadata.is_opaque = true;
@ -1335,10 +1342,10 @@ impl From<RadialGradientPrimitiveGpu> for GpuBlock32 {
}
}
impl From<YuvImagePrimitiveGpu> for GpuBlock64 {
fn from(data: YuvImagePrimitiveGpu) -> GpuBlock64 {
impl From<YuvImagePrimitiveGpu> for GpuBlock16 {
fn from(data: YuvImagePrimitiveGpu) -> GpuBlock16 {
unsafe {
mem::transmute::<YuvImagePrimitiveGpu, GpuBlock64>(data)
mem::transmute::<YuvImagePrimitiveGpu, GpuBlock16>(data)
}
}
}

Просмотреть файл

@ -68,6 +68,10 @@ impl IntProfileCounter {
pub fn set(&mut self, amount: usize) {
self.value = amount;
}
pub fn get(&self) -> usize {
self.value
}
}
impl ProfileCounter for IntProfileCounter {
@ -153,6 +157,10 @@ impl TimeProfileCounter {
self.nanoseconds += ns;
val
}
pub fn get(&self) -> u64 {
self.nanoseconds
}
}
impl ProfileCounter for TimeProfileCounter {

Просмотреть файл

@ -66,6 +66,7 @@ pub fn should_record_msg(msg: &ApiMsg) -> bool {
match msg {
&ApiMsg::AddRawFont(..) |
&ApiMsg::AddNativeFont(..) |
&ApiMsg::DeleteFont(..) |
&ApiMsg::AddImage(..) |
&ApiMsg::GenerateFrame(..) |
&ApiMsg::UpdateImage(..) |

Просмотреть файл

@ -18,6 +18,7 @@ use std::sync::mpsc::Sender;
use texture_cache::TextureCache;
use thread_profiler::register_thread_with_profiler;
use threadpool::ThreadPool;
use webrender_traits::{DeviceIntPoint, DeviceUintPoint, DeviceUintRect, DeviceUintSize, LayerPoint};
use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, ImageData};
use webrender_traits::{PipelineId, RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId};
use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver};
@ -34,7 +35,13 @@ pub struct RenderBackend {
payload_tx: PayloadSender,
result_tx: Sender<ResultMsg>,
device_pixel_ratio: f32,
// TODO(gw): Consider using strongly typed units here.
hidpi_factor: f32,
page_zoom_factor: f32,
pinch_zoom_factor: f32,
pan: DeviceIntPoint,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect,
next_namespace_id: IdNamespace,
resource_cache: ResourceCache,
@ -59,7 +66,7 @@ impl RenderBackend {
payload_rx: PayloadReceiver,
payload_tx: PayloadSender,
result_tx: Sender<ResultMsg>,
device_pixel_ratio: f32,
hidpi_factor: f32,
texture_cache: TextureCache,
enable_aa: bool,
workers: Arc<Mutex<ThreadPool>>,
@ -69,7 +76,8 @@ impl RenderBackend {
recorder: Option<Box<ApiRecordingReceiver>>,
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>,
blob_image_renderer: Option<Box<BlobImageRenderer>>,
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>) -> RenderBackend {
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>,
initial_window_size: DeviceUintSize) -> RenderBackend {
let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer, enable_aa);
@ -80,7 +88,10 @@ impl RenderBackend {
payload_rx: payload_rx,
payload_tx: payload_tx,
result_tx: result_tx,
device_pixel_ratio: device_pixel_ratio,
hidpi_factor: hidpi_factor,
page_zoom_factor: 1.0,
pinch_zoom_factor: 1.0,
pan: DeviceIntPoint::zero(),
resource_cache: resource_cache,
scene: Scene::new(),
frame: Frame::new(config),
@ -92,7 +103,9 @@ impl RenderBackend {
recorder: recorder,
main_thread_dispatcher: main_thread_dispatcher,
next_webgl_id: 0,
vr_compositor_handler: vr_compositor_handler
vr_compositor_handler: vr_compositor_handler,
window_size: initial_window_size,
inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_window_size),
}
}
@ -117,6 +130,9 @@ impl RenderBackend {
self.resource_cache
.add_font_template(id, FontTemplate::Native(native_font_handle));
}
ApiMsg::DeleteFont(id) => {
self.resource_cache.delete_font_template(id);
}
ApiMsg::GetGlyphDimensions(glyph_keys, tx) => {
let mut glyph_dimensions = Vec::with_capacity(glyph_keys.len());
for glyph_key in &glyph_keys {
@ -137,6 +153,19 @@ impl RenderBackend {
ApiMsg::DeleteImage(id) => {
self.resource_cache.delete_image_template(id);
}
ApiMsg::SetPageZoom(factor) => {
self.page_zoom_factor = factor.get();
}
ApiMsg::SetPinchZoom(factor) => {
self.pinch_zoom_factor = factor.get();
}
ApiMsg::SetPan(pan) => {
self.pan = pan;
}
ApiMsg::SetWindowParameters(window_size, inner_rect) => {
self.window_size = window_size;
self.inner_rect = inner_rect;
}
ApiMsg::CloneApi(sender) => {
let result = self.next_namespace_id;
@ -398,6 +427,10 @@ impl RenderBackend {
self.frame.discard_frame_state_for_pipeline(pipeline_id);
}
fn accumulated_scale_factor(&self) -> f32 {
self.hidpi_factor * self.page_zoom_factor * self.pinch_zoom_factor
}
fn build_scene(&mut self) {
// Flatten the stacking context hierarchy
if let Some(id) = self.current_bound_webgl_context_id {
@ -418,17 +451,25 @@ impl RenderBackend {
webgl_context.unbind();
}
self.frame.create(&self.scene, &mut self.resource_cache);
let accumulated_scale_factor = self.accumulated_scale_factor();
self.frame.create(&self.scene,
&mut self.resource_cache,
self.window_size,
self.inner_rect,
accumulated_scale_factor);
}
fn render(&mut self,
texture_cache_profile: &mut TextureCacheProfileCounters)
-> RendererFrame {
let accumulated_scale_factor = self.accumulated_scale_factor();
let pan = LayerPoint::new(self.pan.x as f32 / accumulated_scale_factor,
self.pan.y as f32 / accumulated_scale_factor);
let frame = self.frame.build(&mut self.resource_cache,
&self.scene.pipeline_auxiliary_lists,
self.device_pixel_ratio,
accumulated_scale_factor,
pan,
texture_cache_profile);
frame
}

Просмотреть файл

@ -7,9 +7,9 @@ use mask_cache::MaskCacheInfo;
use prim_store::{PrimitiveCacheKey, PrimitiveIndex};
use std::{cmp, f32, i32, mem, usize};
use tiling::{ClipScrollGroupIndex, PackedLayerIndex, RenderPass, RenderTargetIndex};
use tiling::{ScrollLayerIndex, StackingContextIndex};
use tiling::{StackingContextIndex};
use webrender_traits::{DeviceIntLength, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
use webrender_traits::MixBlendMode;
use webrender_traits::{MixBlendMode, ScrollLayerId};
const FLOATS_PER_RENDER_TASK_INFO: usize = 12;
@ -33,7 +33,7 @@ pub enum RenderTaskKey {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum MaskCacheKey {
Primitive(PrimitiveIndex),
ScrollLayer(ScrollLayerIndex),
ScrollLayer(ScrollLayerId),
}
#[derive(Debug, Copy, Clone)]
@ -62,6 +62,7 @@ pub struct AlphaRenderTask {
screen_origin: DeviceIntPoint,
pub opaque_items: Vec<AlphaRenderItem>,
pub alpha_items: Vec<AlphaRenderItem>,
pub isolate_clear: bool,
}
#[derive(Debug, Copy, Clone)]
@ -144,6 +145,7 @@ pub struct RenderTask {
impl RenderTask {
pub fn new_alpha_batch(task_index: RenderTaskIndex,
screen_origin: DeviceIntPoint,
isolate_clear: bool,
location: RenderTaskLocation) -> RenderTask {
RenderTask {
id: RenderTaskId::Static(task_index),
@ -153,6 +155,7 @@ impl RenderTask {
screen_origin: screen_origin,
alpha_items: Vec::new(),
opaque_items: Vec::new(),
isolate_clear: isolate_clear,
}),
}
}

Просмотреть файл

@ -11,8 +11,8 @@
use debug_colors;
use debug_render::DebugRenderer;
use device::{DepthFunction, Device, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler};
use device::{TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError};
use device::{DepthFunction, Device, FrameId, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler};
use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError};
use euclid::Matrix4D;
use fnv::FnvHasher;
use frame_builder::FrameBuilderConfig;
@ -29,7 +29,7 @@ use render_backend::RenderBackend;
use render_task::RenderTaskData;
use std;
use std::cmp;
use std::collections::HashMap;
use std::collections::{HashMap, VecDeque};
use std::f32;
use std::hash::BuildHasherDefault;
use std::marker::PhantomData;
@ -46,7 +46,7 @@ use time::precise_time_ns;
use thread_profiler::{register_thread_with_profiler, write_profile};
use util::TransformedRectKind;
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher};
use webrender_traits::{ExternalImageId, ImageData, ImageFormat, RenderApiSender, RendererKind};
use webrender_traits::{ExternalImageId, ImageData, ImageFormat, RenderApiSender};
use webrender_traits::{DeviceIntRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
use webrender_traits::{ImageDescriptor, BlobImageRenderer};
use webrender_traits::channel;
@ -75,14 +75,55 @@ const GPU_TAG_PRIM_BORDER: GpuProfileTag = GpuProfileTag { label: "Border", colo
const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { label: "CacheImage", color: debug_colors::SILVER };
const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { label: "Blur", color: debug_colors::VIOLET };
#[derive(Debug, Copy, Clone)]
pub enum RendererKind {
Native,
OSMesa,
}
#[derive(Debug)]
pub struct GpuProfile {
pub frame_id: FrameId,
pub paint_time_ns: u64,
}
impl GpuProfile {
fn new<T>(frame_id: FrameId, samples: &[GpuSample<T>]) -> GpuProfile {
let mut paint_time_ns = 0;
for sample in samples {
paint_time_ns += sample.time_ns;
}
GpuProfile {
frame_id: frame_id,
paint_time_ns: paint_time_ns,
}
}
}
#[derive(Debug)]
pub struct CpuProfile {
pub frame_id: FrameId,
pub composite_time_ns: u64,
pub draw_calls: usize,
}
impl CpuProfile {
fn new(frame_id: FrameId,
composite_time_ns: u64,
draw_calls: usize) -> CpuProfile {
CpuProfile {
frame_id: frame_id,
composite_time_ns: composite_time_ns,
draw_calls: draw_calls,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum BlendMode {
None,
Alpha,
Multiply,
Max,
Min,
PremultipliedAlpha,
// Use the color of the text itself as a constant color blend factor.
Subpixel(ColorF),
@ -429,6 +470,7 @@ pub struct Renderer {
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
enable_profiler: bool,
max_recorded_profiles: usize,
clear_framebuffer: bool,
clear_color: ColorF,
debug: DebugRenderer,
@ -477,7 +519,12 @@ pub struct Renderer {
// Optional trait object that handles WebVR commands.
// Some WebVR commands such as SubmitFrame must be synced with the WebGL render thread.
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>,
/// List of profile results from previous frames. Can be retrieved
/// via get_frame_profiles().
cpu_profiles: VecDeque<CpuProfile>,
gpu_profiles: VecDeque<GpuProfile>,
}
#[derive(Debug)]
@ -513,7 +560,8 @@ impl Renderer {
/// };
/// let (renderer, sender) = Renderer::new(opts);
/// ```
pub fn new(mut options: RendererOptions) -> Result<(Renderer, RenderApiSender), InitError> {
pub fn new(mut options: RendererOptions,
initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> {
let (api_tx, api_rx) = try!{ channel::msg_channel() };
let (payload_tx, payload_rx) = try!{ channel::payload_channel() };
let (result_tx, result_rx) = channel();
@ -805,7 +853,8 @@ impl Renderer {
recorder,
backend_main_thread_dispatcher,
blob_image_renderer,
backend_vr_compositor);
backend_vr_compositor,
initial_window_size);
backend.run(backend_profile_counters);
})};
@ -842,6 +891,7 @@ impl Renderer {
profile_counters: RendererProfileCounters::new(),
profiler: Profiler::new(),
enable_profiler: options.enable_profiler,
max_recorded_profiles: options.max_recorded_profiles,
clear_framebuffer: options.clear_framebuffer,
clear_color: options.clear_color,
last_time: 0,
@ -858,7 +908,9 @@ impl Renderer {
dummy_cache_texture_id: dummy_cache_texture_id,
external_image_handler: None,
external_images: HashMap::with_hasher(Default::default()),
vr_compositor_handler: vr_compositor
vr_compositor_handler: vr_compositor,
cpu_profiles: VecDeque::new(),
gpu_profiles: VecDeque::new(),
};
let sender = RenderApiSender::new(api_tx, payload_tx);
@ -960,6 +1012,13 @@ impl Renderer {
self.external_image_handler = Some(handler);
}
/// Retrieve (and clear) the current list of recorded frame profiles.
pub fn get_frame_profiles(&mut self) -> (Vec<CpuProfile>, Vec<GpuProfile>) {
let cpu_profiles = self.cpu_profiles.drain(..).collect();
let gpu_profiles = self.gpu_profiles.drain(..).collect();
(cpu_profiles, gpu_profiles)
}
/// Renders the current frame.
///
/// A Frame is supplied by calling [set_root_stacking_context()][newframe].
@ -973,13 +1032,19 @@ impl Renderer {
// Block CPU waiting for last frame's GPU profiles to arrive.
// In general this shouldn't block unless heavily GPU limited.
if let Some(samples) = self.gpu_profile.build_samples() {
if let Some((gpu_frame_id, samples)) = self.gpu_profile.build_samples() {
if self.max_recorded_profiles > 0 {
while self.gpu_profiles.len() >= self.max_recorded_profiles {
self.gpu_profiles.pop_front();
}
self.gpu_profiles.push_back(GpuProfile::new(gpu_frame_id, &samples));
}
profile_timers.gpu_samples = samples;
}
profile_timers.cpu_time.profile(|| {
self.device.begin_frame(frame.device_pixel_ratio);
self.gpu_profile.begin_frame();
let cpu_frame_id = profile_timers.cpu_time.profile(|| {
let cpu_frame_id = self.device.begin_frame(frame.device_pixel_ratio);
self.gpu_profile.begin_frame(cpu_frame_id);
{
let _gm = self.gpu_profile.add_marker(GPU_TAG_INIT);
@ -994,12 +1059,23 @@ impl Renderer {
self.draw_tile_frame(frame, &framebuffer_size);
self.gpu_profile.end_frame();
cpu_frame_id
});
let current_time = precise_time_ns();
let ns = current_time - self.last_time;
self.profile_counters.frame_time.set(ns);
if self.max_recorded_profiles > 0 {
while self.cpu_profiles.len() >= self.max_recorded_profiles {
self.cpu_profiles.pop_front();
}
let cpu_profile = CpuProfile::new(cpu_frame_id,
profile_timers.cpu_time.get(),
self.profile_counters.draw_calls.get());
self.cpu_profiles.push_back(cpu_profile);
}
if self.enable_profiler {
self.profiler.draw_profile(&frame.profile_counters,
&self.backend_profile_counters,
@ -1180,7 +1256,9 @@ impl Renderer {
target_dimensions: DeviceUintSize) {
let transform_kind = batch.key.flags.transform_kind();
let needs_clipping = batch.key.flags.needs_clipping();
debug_assert!(!needs_clipping || batch.key.blend_mode == BlendMode::Alpha);
debug_assert!(!needs_clipping ||
batch.key.blend_mode == BlendMode::Alpha ||
batch.key.blend_mode == BlendMode::PremultipliedAlpha);
match batch.data {
PrimitiveBatchData::Instances(ref data) => {
@ -1205,8 +1283,7 @@ impl Renderer {
AlphaBatchKind::TextRun => {
let shader = match batch.key.blend_mode {
BlendMode::Subpixel(..) => self.ps_text_run_subpixel.get(&mut self.device, transform_kind),
BlendMode::Alpha | BlendMode::None => self.ps_text_run.get(&mut self.device, transform_kind),
_ => unreachable!(),
BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::None => self.ps_text_run.get(&mut self.device, transform_kind),
};
(GPU_TAG_PRIM_TEXT_RUN, shader)
}
@ -1290,20 +1367,18 @@ impl Renderer {
let width = readback.data[2];
let height = readback.data[3];
// Need to invert the y coordinates when reading back from
// the framebuffer.
let y0 = if render_target.is_some() {
src_y as i32
} else {
target_dimensions.height as i32 - height as i32 - src_y as i32
};
let mut src = DeviceIntRect::new(DeviceIntPoint::new(src_x as i32, src_y as i32),
DeviceIntSize::new(width as i32, height as i32));
let mut dest = DeviceIntRect::new(DeviceIntPoint::new(dest_x as i32, dest_y as i32),
DeviceIntSize::new(width as i32, height as i32));
let src = DeviceIntRect::new(DeviceIntPoint::new(src_x as i32,
y0),
DeviceIntSize::new(width as i32, height as i32));
let dest = DeviceIntRect::new(DeviceIntPoint::new(dest_x as i32,
dest_y as i32),
DeviceIntSize::new(width as i32, height as i32));
// Need to invert the y coordinates and flip the image vertically when
// reading back from the framebuffer.
if render_target.is_none() {
src.origin.y = target_dimensions.height as i32 - src.size.height - src.origin.y;
dest.origin.y += dest.size.height;
dest.size.height = -dest.size.height;
}
self.device.blit_render_target(render_target,
Some(src),
@ -1381,6 +1456,11 @@ impl Renderer {
self.device.clear_target(clear_color, clear_depth);
let isolate_clear_color = Some([0.0, 0.0, 0.0, 0.0]);
for isolate_clear in &target.isolate_clears {
self.device.clear_target_rect(isolate_clear_color, None, *isolate_clear);
}
projection
};
@ -1501,22 +1581,14 @@ impl Renderer {
BlendMode::None => {
self.device.set_blend(false);
}
BlendMode::Multiply => {
self.device.set_blend(true);
self.device.set_blend_mode_multiply();
}
BlendMode::Max => {
self.device.set_blend(true);
self.device.set_blend_mode_max();
}
BlendMode::Min => {
self.device.set_blend(true);
self.device.set_blend_mode_min();
}
BlendMode::Alpha => {
self.device.set_blend(true);
self.device.set_blend_mode_alpha();
}
BlendMode::PremultipliedAlpha => {
self.device.set_blend(true);
self.device.set_blend_mode_premultiplied_alpha();
}
BlendMode::Subpixel(color) => {
self.device.set_blend(true);
self.device.set_blend_mode_subpixel(color);
@ -1601,10 +1673,8 @@ impl Renderer {
// Some tests use a restricted viewport smaller than the main screen size.
// Ensure we clear the framebuffer in these tests.
// TODO(gw): Find a better solution for this?
let viewport_size = DeviceIntSize::new((frame.viewport_size.width * frame.device_pixel_ratio) as i32,
(frame.viewport_size.height * frame.device_pixel_ratio) as i32);
let needs_clear = viewport_size.width < framebuffer_size.width as i32 ||
viewport_size.height < framebuffer_size.height as i32;
let needs_clear = frame.window_size.width < framebuffer_size.width ||
frame.window_size.height < framebuffer_size.height;
self.device.disable_depth_write();
self.device.disable_stencil();
@ -1778,6 +1848,7 @@ pub struct RendererOptions {
pub resource_override_path: Option<PathBuf>,
pub enable_aa: bool,
pub enable_profiler: bool,
pub max_recorded_profiles: usize,
pub debug: bool,
pub enable_scrollbars: bool,
pub precache_shaders: bool,
@ -1799,6 +1870,7 @@ impl Default for RendererOptions {
resource_override_path: None,
enable_aa: true,
enable_profiler: false,
max_recorded_profiles: 0,
debug: false,
enable_scrollbars: false,
precache_shaders: false,

Просмотреть файл

@ -41,6 +41,8 @@ enum GlyphCacheMsg {
AddFont(FontKey, FontTemplate),
/// Request glyphs for a text run.
RequestGlyphs(FontKey, Au, ColorF, Vec<GlyphInstance>, FontRenderMode, Option<GlyphOptions>),
// Remove an existing font.
DeleteFont(FontKey),
/// Finished requesting glyphs. Reply with new glyphs.
EndFrame,
}
@ -260,6 +262,13 @@ impl ResourceCache {
self.font_templates.insert(font_key, template);
}
pub fn delete_font_template(&mut self, font_key: FontKey) {
self.glyph_cache_tx
.send(GlyphCacheMsg::DeleteFont(font_key))
.unwrap();
self.font_templates.remove(&font_key);
}
pub fn add_image_template(&mut self,
image_key: ImageKey,
descriptor: ImageDescriptor,
@ -839,6 +848,23 @@ fn spawn_glyph_cache_thread(workers: Arc<Mutex<ThreadPool>>) -> (Sender<GlyphCac
});
}
}
GlyphCacheMsg::DeleteFont(font_key) => {
profile_scope!("DeleteFont");
// Delete a font from the font context in each worker thread.
let barrier = Arc::new(Barrier::new(worker_count));
for _ in 0..worker_count {
let barrier = barrier.clone();
workers.lock().unwrap().execute(move || {
FONT_CONTEXT.with(|font_context| {
let mut font_context = font_context.borrow_mut();
font_context.delete_font(&font_key);
});
barrier.wait();
});
}
}
GlyphCacheMsg::RequestGlyphs(key, size, color, glyph_instances, render_mode, glyph_options) => {
profile_scope!("RequestGlyphs");

Просмотреть файл

@ -41,7 +41,14 @@ impl SceneProperties {
}
/// Get the current value for a transform property.
pub fn resolve_layout_transform(&self, property: &PropertyBinding<LayoutTransform>) -> LayoutTransform {
pub fn resolve_layout_transform(&self,
property: Option<&PropertyBinding<LayoutTransform>>)
-> LayoutTransform {
let property = match property {
Some(property) => property,
None => return LayoutTransform::identity(),
};
match *property {
PropertyBinding::Value(matrix) => matrix,
PropertyBinding::Binding(ref key) => {

Просмотреть файл

@ -7,7 +7,7 @@ use fnv::FnvHasher;
use gpu_store::GpuStoreAddress;
use internal_types::{ANGLE_FLOAT_TO_FIXED, BatchTextures, CacheTextureId, LowLevelFilterOp};
use internal_types::SourceTexture;
use mask_cache::{ClipSource, MaskCacheInfo};
use mask_cache::MaskCacheInfo;
use prim_store::{CLIP_DATA_GPU_SIZE, DeferredResolve, GpuBlock128, GpuBlock16, GpuBlock32};
use prim_store::{GpuBlock64, GradientData, PrimitiveCacheKey, PrimitiveGeometry, PrimitiveIndex};
use prim_store::{PrimitiveKind, PrimitiveMetadata, PrimitiveStore, TexelRect};
@ -23,9 +23,9 @@ use std::hash::BuildHasherDefault;
use texture_cache::TexturePage;
use util::{TransformedRect, TransformedRectKind};
use webrender_traits::{AuxiliaryLists, ColorF, DeviceIntPoint, DeviceIntRect, DeviceUintPoint};
use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerRect, LayerSize};
use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, MixBlendMode, PipelineId};
use webrender_traits::{ScrollLayerId, WorldPoint4D, WorldToLayerTransform};
use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerPoint, LayerRect};
use webrender_traits::{LayerToWorldTransform, MixBlendMode, PipelineId, ScrollLayerId};
use webrender_traits::{WorldPoint4D, WorldToLayerTransform};
// Special sentinel value recognized by the shader. It is considered to be
// a dummy task that doesn't mask out anything.
@ -105,7 +105,7 @@ impl AlphaBatchHelpers for PrimitiveStore {
}
PrimitiveKind::YuvImage => {
let image_cpu = &self.cpu_yuv_images[metadata.cpu_prim_index.0];
[image_cpu.y_texture_id, image_cpu.u_texture_id, image_cpu.v_texture_id]
image_cpu.yuv_texture_id
}
PrimitiveKind::TextRun => {
let text_run_cpu = &self.cpu_text_runs[metadata.cpu_prim_index.0];
@ -128,6 +128,13 @@ impl AlphaBatchHelpers for PrimitiveStore {
BlendMode::Alpha
}
}
PrimitiveKind::Image => {
if needs_blending {
BlendMode::PremultipliedAlpha
} else {
BlendMode::None
}
}
_ => {
if needs_blending {
BlendMode::Alpha
@ -277,6 +284,8 @@ impl AlphaBatchHelpers for PrimitiveStore {
});
}
AlphaBatchKind::YuvImage => {
let image_yuv_cpu = &self.cpu_yuv_images[metadata.cpu_prim_index.0];
data.push(PrimitiveInstance {
task_index: task_index,
clip_task_index: clip_task_index,
@ -284,7 +293,7 @@ impl AlphaBatchHelpers for PrimitiveStore {
global_prim_id: global_prim_id,
prim_address: prim_address,
sub_index: 0,
user_data: [ 0, 0 ],
user_data: [ image_yuv_cpu.yuv_resource_address.0, 0 ],
z_sort_index: z_sort_index,
});
}
@ -391,14 +400,11 @@ pub struct ScrollbarPrimitive {
pub border_radius: f32,
}
#[derive(Debug)]
pub enum PrimitiveRunCmd {
PushStackingContext(StackingContextIndex),
PopStackingContext,
PushScrollLayer(ScrollLayerIndex),
PopScrollLayer,
PrimitiveRun(PrimitiveIndex, usize),
PrimitiveRun(PrimitiveIndex, usize, ScrollLayerId),
}
#[derive(Debug, Copy, Clone)]
@ -870,6 +876,7 @@ pub struct RenderTarget {
pub vertical_blurs: Vec<BlurCommand>,
pub horizontal_blurs: Vec<BlurCommand>,
pub readbacks: Vec<DeviceIntRect>,
pub isolate_clears: Vec<DeviceIntRect>,
page_allocator: TexturePage,
}
@ -884,6 +891,7 @@ impl RenderTarget {
vertical_blurs: Vec::new(),
horizontal_blurs: Vec::new(),
readbacks: Vec::new(),
isolate_clears: Vec::new(),
page_allocator: TexturePage::new(CacheTextureId(0), size),
}
}
@ -909,6 +917,16 @@ impl RenderTarget {
opaque_items: info.opaque_items,
alpha_items: info.alpha_items,
});
if info.isolate_clear {
let location = match task.location {
RenderTaskLocation::Dynamic(origin, size) => {
DeviceIntRect::new(origin.unwrap().0, size)
}
RenderTaskLocation::Fixed => panic!()
};
self.isolate_clears.push(location);
}
}
RenderTaskKind::VerticalBlur(_, prim_index) => {
// Find the child render task that we are applying
@ -1301,53 +1319,79 @@ pub struct StackingContextIndex(pub usize);
#[derive(Debug)]
pub struct StackingContext {
pub pipeline_id: PipelineId,
pub local_transform: LayerToScrollTransform,
// Offset in the parent reference frame to the origin of this stacking
// context's coordinate system.
pub reference_frame_offset: LayerPoint,
// Bounds of this stacking context in its own coordinate system.
pub local_rect: LayerRect,
pub bounding_rect: DeviceIntRect,
pub composite_ops: CompositeOps,
pub clip_scroll_groups: Vec<ClipScrollGroupIndex>,
// Signifies that this stacking context should be drawn in a separate render pass
// with a transparent background and then composited back to its parent. Used to
// support mix-blend-mode in certain cases.
pub should_isolate: bool,
// Set for the root stacking context of a display list or an iframe. Used for determining
// when to isolate a mix-blend-mode composite.
pub is_page_root: bool,
pub is_visible: bool,
}
impl StackingContext {
pub fn new(pipeline_id: PipelineId,
local_transform: LayerToScrollTransform,
reference_frame_offset: LayerPoint,
local_rect: LayerRect,
composite_ops: CompositeOps,
clip_scroll_group_index: ClipScrollGroupIndex)
is_page_root: bool,
composite_ops: CompositeOps)
-> StackingContext {
StackingContext {
pipeline_id: pipeline_id,
local_transform: local_transform,
reference_frame_offset: reference_frame_offset,
local_rect: local_rect,
bounding_rect: DeviceIntRect::zero(),
composite_ops: composite_ops,
clip_scroll_groups: vec![clip_scroll_group_index],
clip_scroll_groups: Vec::new(),
should_isolate: false,
is_page_root: is_page_root,
is_visible: false,
}
}
pub fn clip_scroll_group(&self) -> ClipScrollGroupIndex {
pub fn clip_scroll_group(&self, scroll_layer_id: ScrollLayerId) -> ClipScrollGroupIndex {
// Currently there is only one scrolled stacking context per context,
// but eventually this will be selected from the vector based on the
// scroll layer of this primitive.
self.clip_scroll_groups[0]
for group in &self.clip_scroll_groups {
if group.1 == scroll_layer_id {
return *group;
}
}
unreachable!("Looking for non-existent ClipScrollGroup");
}
pub fn can_contribute_to_scene(&self) -> bool {
!self.composite_ops.will_make_invisible()
}
pub fn has_clip_scroll_group(&self, id: ScrollLayerId) -> bool {
self.clip_scroll_groups.iter().rev().any(|index| index.1 == id)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ClipScrollGroupIndex(pub usize);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct ClipScrollGroupIndex(pub usize, pub ScrollLayerId);
#[derive(Debug)]
pub struct ClipScrollGroup {
pub stacking_context_index: StackingContextIndex,
pub scroll_layer_id: ScrollLayerId,
pub packed_layer_index: PackedLayerIndex,
pub pipeline_id: PipelineId,
pub xf_rect: Option<TransformedRect>,
}
@ -1357,18 +1401,6 @@ impl ClipScrollGroup {
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ScrollLayerIndex(pub usize);
pub struct ScrollLayer {
pub scroll_layer_id: ScrollLayerId,
pub parent_index: ScrollLayerIndex,
pub clip_source: ClipSource,
pub clip_cache_info: Option<MaskCacheInfo>,
pub packed_layer_index: PackedLayerIndex,
pub xf_rect: Option<TransformedRect>,
}
#[derive(Debug, Clone)]
#[repr(C)]
pub struct PackedLayer {
@ -1393,6 +1425,31 @@ impl PackedLayer {
pub fn empty() -> PackedLayer {
Default::default()
}
pub fn set_transform(&mut self, transform: LayerToWorldTransform) {
self.transform = transform;
self.inv_transform = self.transform.inverse().unwrap();
}
pub fn set_rect(&mut self,
local_rect: Option<LayerRect>,
screen_rect: &DeviceIntRect,
device_pixel_ratio: f32)
-> Option<TransformedRect> {
let local_rect = match local_rect {
Some(rect) if !rect.is_empty() => rect,
_ => return None,
};
let xf_rect = TransformedRect::new(&local_rect, &self.transform, device_pixel_ratio);
if !xf_rect.bounding_rect.intersects(screen_rect) {
return None;
}
self.screen_vertices = xf_rect.vertices.clone();
self.local_clip_rect = local_rect;
Some(xf_rect)
}
}
#[derive(Debug, Clone)]
@ -1412,13 +1469,6 @@ impl CompositeOps {
}
}
pub fn empty() -> CompositeOps {
CompositeOps {
filters: Vec::new(),
mix_blend_mode: None,
}
}
pub fn count(&self) -> usize {
self.filters.len() + if self.mix_blend_mode.is_some() { 1 } else { 0 }
}
@ -1437,7 +1487,7 @@ impl CompositeOps {
/// A rendering-oriented representation of frame::Frame built by the render backend
/// and presented to the renderer.
pub struct Frame {
pub viewport_size: LayerSize,
pub window_size: DeviceUintSize,
pub background_color: Option<ColorF>,
pub device_pixel_ratio: f32,
pub cache_size: DeviceUintSize,

Просмотреть файл

@ -5,13 +5,12 @@ authors = ["The Mozilla Project Developers"]
license = "MPL-2.0"
[dependencies]
webrender_traits = {path = "../webrender_traits", version = "0.20.0"}
webrender_traits = {path = "../webrender_traits", version = "0.25.0"}
euclid = "0.11"
app_units = "0.4"
gleam = "0.2"
[dependencies.webrender]
path = "../webrender"
version = "0.19.0"
version = "0.24.0"
default-features = false
features = ["codegen"]

Просмотреть файл

@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RenderTextureHost.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/ImageDataSerializer.h"
namespace mozilla {
using namespace gfx;
using namespace layers;
namespace wr {
RenderTextureHost::RenderTextureHost(uint8_t* aBuffer, const BufferDescriptor& aDescriptor)
: mBuffer(aBuffer)
, mDescriptor(aDescriptor)
, mLocked(false)
{
MOZ_COUNT_CTOR(RenderTextureHost);
switch (mDescriptor.type()) {
case BufferDescriptor::TYCbCrDescriptor: {
const YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
mSize = ycbcr.ySize();
mFormat = gfx::SurfaceFormat::YUV;
break;
}
case BufferDescriptor::TRGBDescriptor: {
const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
mSize = rgb.size();
mFormat = rgb.format();
break;
}
default:
gfxCriticalError() << "Bad buffer host descriptor " << (int)mDescriptor.type();
MOZ_CRASH("GFX: Bad descriptor");
}
}
RenderTextureHost::~RenderTextureHost()
{
MOZ_COUNT_DTOR(RenderTextureHost);
}
already_AddRefed<gfx::DataSourceSurface>
RenderTextureHost::GetAsSurface()
{
RefPtr<gfx::DataSourceSurface> result;
if (mFormat == gfx::SurfaceFormat::YUV) {
result = ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
GetBuffer(), mDescriptor.get_YCbCrDescriptor());
if (NS_WARN_IF(!result)) {
return nullptr;
}
} else {
result =
gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
mSize, mFormat);
}
return result.forget();
}
bool
RenderTextureHost::Lock()
{
MOZ_ASSERT(!mLocked);
// XXX temporal workaround for YUV handling
if (!mSurface) {
mSurface = GetAsSurface();
if (!mSurface) {
return false;
}
}
if (NS_WARN_IF(!mSurface->Map(DataSourceSurface::MapType::READ_WRITE, &mMap))) {
mSurface = nullptr;
return false;
}
mLocked = true;
return true;
}
void
RenderTextureHost::Unlock()
{
MOZ_ASSERT(mLocked);
mLocked = false;
if (mSurface) {
mSurface->Unmap();
}
mSurface = nullptr;
}
uint8_t*
RenderTextureHost::GetDataForRender() const
{
MOZ_ASSERT(mLocked);
MOZ_ASSERT(mSurface);
return mMap.mData;
}
size_t
RenderTextureHost::GetBufferSizeForRender() const
{
MOZ_ASSERT(mLocked);
MOZ_ASSERT(mSurface);
return mMap.mStride * mSurface->GetSize().height;
}
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_RENDERTEXTUREHOST_H
#define MOZILLA_GFX_RENDERTEXTUREHOST_H
#include "nsISupportsImpl.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace wr {
class RenderTextureHost
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost)
RenderTextureHost(uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor);
bool Lock();
void Unlock();
gfx::IntSize GetSize() const { return mSize; }
gfx::SurfaceFormat GetFormat() const { return mFormat; }
uint8_t* GetDataForRender() const;
size_t GetBufferSizeForRender() const;
protected:
~RenderTextureHost();
already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
uint8_t* GetBuffer() const { return mBuffer; }
uint8_t* mBuffer;
layers::BufferDescriptor mDescriptor;
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
RefPtr<gfx::DataSourceSurface> mSurface;
gfx::DataSourceSurface::MappedSurface mMap;
bool mLocked;
};
} // namespace wr
} // namespace mozilla
#endif // MOZILLA_GFX_RENDERTEXTUREHOST_H

Просмотреть файл

@ -5,11 +5,12 @@
#include "RenderThread.h"
#include "nsThreadUtils.h"
#include "mozilla/webrender/RendererOGL.h"
#include "mozilla/widget/CompositorWidget.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/webrender/RendererOGL.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/widget/CompositorWidget.h"
#include "base/task.h"
namespace mozilla {
@ -19,6 +20,7 @@ static StaticRefPtr<RenderThread> sRenderThread;
RenderThread::RenderThread(base::Thread* aThread)
: mThread(aThread)
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
{
}
@ -194,6 +196,30 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId)
));
}
void
RenderThread::RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(!mRenderTextures.Get(aExternalImageId));
mRenderTextures.Put(aExternalImageId, aTexture);
}
void
RenderThread::UnregisterExternalImage(uint64_t aExternalImageId)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(mRenderTextures.Get(aExternalImageId).get());
mRenderTextures.Remove(aExternalImageId);
}
RenderTextureHost*
RenderThread::GetRenderTexture(uint64_t aExternalImageId)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(mRenderTextures.Get(aExternalImageId).get());
return mRenderTextures.Get(aExternalImageId).get();
}
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "nsISupportsImpl.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/Mutex.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -21,6 +22,7 @@ namespace mozilla {
namespace wr {
class RendererOGL;
class RenderTextureHost;
class RenderThread;
/// Base class for an event that can be scheduled to run on the render thread.
@ -99,6 +101,13 @@ public:
/// Can only be called from the render thread.
void UpdateAndRender(wr::WindowId aWindowId);
void RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture);
void UnregisterExternalImage(uint64_t aExternalImageId);
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
private:
explicit RenderThread(base::Thread* aThread);
@ -108,6 +117,9 @@ private:
base::Thread* const mThread;
std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
Mutex mRenderTextureMapLock;
nsDataHashtable<nsUint64HashKey, RefPtr<RenderTextureHost> > mRenderTextures;
};
} // namespace wr

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/widget/CompositorWidget.h"
namespace mozilla {
@ -16,11 +17,20 @@ namespace wr {
WrExternalImage LockExternalImage(void* aObj, WrExternalImageId aId)
{
return WrExternalImage { /*WrExternalImageIdType::TextureHandle, */0.0f, 0.0f, 0.0f, 0.0f, 0 };
RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
RenderTextureHost* texture = renderer->GetRenderTexture(aId.id);
MOZ_ASSERT(texture);
texture->Lock();
return WrExternalImage { WrExternalImageIdType::RawData, 0.0f, 0.0f, 0.0f, 0.0f, 0,
texture->GetDataForRender(), texture->GetBufferSizeForRender() };
}
void UnlockExternalImage(void* aObj, WrExternalImageId aId)
{
RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
RenderTextureHost* texture = renderer->GetRenderTexture(aId.id);
MOZ_ASSERT(texture);
texture->Unlock();
}
void ReleaseExternalImage(void* aObj, WrExternalImageId aId)
@ -120,5 +130,11 @@ RendererOGL::FlushRenderedEpochs()
return wr_renderer_flush_rendered_epochs(mWrRenderer);
}
RenderTextureHost*
RendererOGL::GetRenderTexture(uint64_t aExternalImageId)
{
return mThread->GetRenderTexture(aExternalImageId);
}
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -31,6 +31,8 @@ class CompositorWidget;
namespace wr {
class RenderTextureHost;
/// Owns the WebRender renderer and GL context.
///
/// There is one renderer per window, all owned by the render thread.
@ -72,6 +74,8 @@ public:
WrRenderedEpochs* FlushRenderedEpochs();
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
protected:
RefPtr<RenderThread> mThread;

Просмотреть файл

@ -21,7 +21,8 @@ public:
bool* aUseANGLE,
RefPtr<widget::CompositorWidget>&& aWidget,
layers::SynchronousTask* aTask,
bool aEnableProfiler)
bool aEnableProfiler,
LayoutDeviceIntSize aSize)
: mWrApi(aApi)
, mMaxTextureSize(aMaxTextureSize)
, mUseANGLE(aUseANGLE)
@ -29,6 +30,7 @@ public:
, mCompositorWidget(Move(aWidget))
, mTask(aTask)
, mEnableProfiler(aEnableProfiler)
, mSize(aSize)
{
MOZ_COUNT_CTOR(NewRenderer);
}
@ -51,7 +53,8 @@ public:
*mUseANGLE = gl->IsANGLE();
WrRenderer* wrRenderer = nullptr;
if (!wr_window_new(aWindowId, gl.get(), this->mEnableProfiler, mWrApi, &wrRenderer)) {
if (!wr_window_new(aWindowId, mSize.width, mSize.height, gl.get(),
this->mEnableProfiler, mWrApi, &wrRenderer)) {
return;
}
MOZ_ASSERT(wrRenderer);
@ -79,6 +82,7 @@ private:
RefPtr<widget::CompositorWidget> mCompositorWidget;
layers::SynchronousTask* mTask;
bool mEnableProfiler;
LayoutDeviceIntSize mSize;
};
class RemoveRenderer : public RendererEvent
@ -110,7 +114,8 @@ private:
already_AddRefed<WebRenderAPI>
WebRenderAPI::Create(bool aEnableProfiler,
layers::CompositorBridgeParentBase* aBridge,
RefPtr<widget::CompositorWidget>&& aWidget)
RefPtr<widget::CompositorWidget>&& aWidget,
LayoutDeviceIntSize aSize)
{
MOZ_ASSERT(aBridge);
MOZ_ASSERT(aWidget);
@ -127,7 +132,7 @@ WebRenderAPI::Create(bool aEnableProfiler,
// the next time we need to access the WrApi object.
layers::SynchronousTask task("Create Renderer");
auto event = MakeUnique<NewRenderer>(&wrApi, aBridge, &maxTextureSize, &useANGLE,
Move(aWidget), &task, aEnableProfiler);
Move(aWidget), &task, aEnableProfiler, aSize);
RenderThread::Get()->RunEvent(id, Move(event));
task.Wait();
@ -184,6 +189,19 @@ WebRenderAPI::SetRootDisplayList(gfx::Color aBgColor,
aux_size);
}
void
WebRenderAPI::ClearRootDisplayList(Epoch aEpoch,
WrPipelineId pipeline_id)
{
wr_api_clear_root_display_list(mWrApi, aEpoch, pipeline_id);
}
void
WebRenderAPI::SetWindowParameters(LayoutDeviceIntSize size)
{
wr_api_set_window_parameters(mWrApi, size.width, size.height);
}
void
WebRenderAPI::Readback(gfx::IntSize size,
uint8_t *buffer,
@ -231,6 +249,42 @@ WebRenderAPI::Readback(gfx::IntSize size,
task.Wait();
}
void
WebRenderAPI::WaitFlushed()
{
class WaitFlushedEvent : public RendererEvent
{
public:
explicit WaitFlushedEvent(layers::SynchronousTask* aTask)
: mTask(aTask)
{
MOZ_COUNT_CTOR(WaitFlushedEvent);
}
~WaitFlushedEvent()
{
MOZ_COUNT_DTOR(WaitFlushedEvent);
}
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
{
layers::AutoCompleteTask complete(mTask);
}
layers::SynchronousTask* mTask;
};
layers::SynchronousTask task("WaitFlushed");
auto event = MakeUnique<WaitFlushedEvent>(&task);
// This event will be passed from wr_backend thread to renderer thread. That
// implies that all frame data have been processed when the renderer runs this
// read-back event. Then, we could make sure this read-back event gets the
// latest result.
RunOnRenderThread(Move(event));
task.Wait();
}
void
WebRenderAPI::SetRootPipeline(PipelineId aPipeline)
{
@ -238,12 +292,12 @@ WebRenderAPI::SetRootPipeline(PipelineId aPipeline)
}
void
WebRenderAPI::AddImage(ImageKey key, const ImageDescriptor& aDescritptor,
WebRenderAPI::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes)
{
wr_api_add_image(mWrApi,
key,
&aDescritptor,
&aDescriptor,
&aBytes[0], aBytes.length());
}
@ -262,25 +316,23 @@ WebRenderAPI::AddExternalImageHandle(ImageKey key,
void
WebRenderAPI::AddExternalImageBuffer(ImageKey key,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
const ImageDescriptor& aDescriptor,
uint64_t aHandle)
{
auto format = SurfaceFormatToWrImageFormat(aFormat).value();
wr_api_add_external_image_buffer(mWrApi,
key,
aSize.width, aSize.height, format,
&aDescriptor,
aHandle);
}
void
WebRenderAPI::UpdateImageBuffer(ImageKey aKey,
const ImageDescriptor& aDescritptor,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes)
{
wr_api_update_image(mWrApi,
aKey,
&aDescritptor,
&aDescriptor,
&aBytes[0], aBytes.length());
}
@ -366,17 +418,16 @@ DisplayListBuilder::End()
wr_dp_end(mWrState);
}
void
DisplayListBuilder::Finalize(WrBuiltDisplayListDescriptor& dl_descriptor,
wr::VecU8& dl_data,
WrAuxiliaryListsDescriptor& aux_descriptor,
wr::VecU8& aux_data)
BuiltDisplayList
DisplayListBuilder::Finalize()
{
wr_api_finalize_builder(mWrState,
dl_descriptor,
dl_data.inner,
aux_descriptor,
aux_data.inner);
BuiltDisplayList dl;
wr_api_finalize_builder(mWrState,
dl.dl_desc,
dl.dl.inner,
dl.aux_desc,
dl.aux.inner);
return dl;
}
void
@ -397,6 +448,16 @@ DisplayListBuilder::PopStackingContext()
wr_dp_pop_stacking_context(mWrState);
}
void
DisplayListBuilder::PushBuiltDisplayList(BuiltDisplayList dl)
{
wr_dp_push_built_display_list(mWrState,
dl.dl_desc,
dl.dl.Extract(),
dl.aux_desc,
dl.aux.Extract());
}
void
DisplayListBuilder::PushScrollLayer(const WrRect& aBounds,
const WrRect& aOverflow,
@ -413,7 +474,7 @@ DisplayListBuilder::PopScrollLayer()
void
DisplayListBuilder::PushRect(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrColor& aColor)
{
wr_dp_push_rect(mWrState, aBounds, aClip, aColor);
@ -421,7 +482,7 @@ DisplayListBuilder::PushRect(const WrRect& aBounds,
void
DisplayListBuilder::PushLinearGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrPoint& aStartPoint,
const WrPoint& aEndPoint,
const nsTArray<WrGradientStop>& aStops,
@ -436,7 +497,7 @@ DisplayListBuilder::PushLinearGradient(const WrRect& aBounds,
void
DisplayListBuilder::PushRadialGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrPoint& aStartCenter,
const WrPoint& aEndCenter,
float aStartRadius,
@ -454,17 +515,16 @@ DisplayListBuilder::PushRadialGradient(const WrRect& aBounds,
void
DisplayListBuilder::PushImage(const WrRect& aBounds,
const WrRect& aClip,
const WrImageMask* aMask,
const WrClipRegion& aClip,
wr::ImageRendering aFilter,
wr::ImageKey aImage)
{
wr_dp_push_image(mWrState, aBounds, aClip, aMask, aFilter, aImage);
wr_dp_push_image(mWrState, aBounds, aClip, aFilter, aImage);
}
void
DisplayListBuilder::PushIFrame(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
PipelineId aPipeline)
{
wr_dp_push_iframe(mWrState, aBounds, aClip, aPipeline);
@ -472,7 +532,8 @@ DisplayListBuilder::PushIFrame(const WrRect& aBounds,
void
DisplayListBuilder::PushBorder(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrBorderWidths& aWidths,
const WrBorderSide& aTop,
const WrBorderSide& aRight,
const WrBorderSide& aBottom,
@ -480,13 +541,27 @@ DisplayListBuilder::PushBorder(const WrRect& aBounds,
const WrBorderRadius& aRadius)
{
wr_dp_push_border(mWrState, aBounds, aClip,
aTop, aRight, aBottom, aLeft,
aRadius);
aWidths, aTop, aRight, aBottom, aLeft, aRadius);
}
void
DisplayListBuilder::PushBorderImage(const WrRect& aBounds,
const WrClipRegion& aClip,
const WrBorderWidths& aWidths,
wr::ImageKey aImage,
const WrNinePatchDescriptor& aPatch,
const WrSideOffsets2Df32& aOutset,
const WrRepeatMode& aRepeatHorizontal,
const WrRepeatMode& aRepeatVertical)
{
wr_dp_push_border_image(mWrState, aBounds, aClip,
aWidths, aImage, aPatch, aOutset,
aRepeatHorizontal, aRepeatVertical);
}
void
DisplayListBuilder::PushText(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const gfx::Color& aColor,
wr::FontKey aFontKey,
Range<const WrGlyphInstance> aGlyphBuffer,
@ -501,7 +576,7 @@ DisplayListBuilder::PushText(const WrRect& aBounds,
void
DisplayListBuilder::PushBoxShadow(const WrRect& aRect,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrRect& aBoxBounds,
const WrPoint& aOffset,
const WrColor& aColor,
@ -516,5 +591,26 @@ DisplayListBuilder::PushBoxShadow(const WrRect& aRect,
aClipMode);
}
WrClipRegion
DisplayListBuilder::BuildClipRegion(const WrRect& aMain,
const WrImageMask* aMask)
{
return wr_dp_new_clip_region(mWrState,
aMain,
nullptr, 0,
aMask);
}
WrClipRegion
DisplayListBuilder::BuildClipRegion(const WrRect& aMain,
const nsTArray<WrComplexClipRegion>& aComplex,
const WrImageMask* aMask)
{
return wr_dp_new_clip_region(mWrState,
aMain,
aComplex.Elements(), aComplex.Length(),
aMask);
}
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/Range.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "GLTypes.h"
#include "Units.h"
namespace mozilla {
@ -21,6 +22,7 @@ class CompositorWidget;
namespace layers {
class CompositorBridgeParentBase;
class WebRenderBridgeParent;
}
namespace wr {
@ -29,8 +31,6 @@ class DisplayListBuilder;
class RendererOGL;
class RendererEvent;
class WebRenderAPI
{
NS_INLINE_DECL_REFCOUNTING(WebRenderAPI);
@ -39,12 +39,14 @@ public:
/// This can be called on the compositor thread only.
static already_AddRefed<WebRenderAPI> Create(bool aEnableProfiler,
layers::CompositorBridgeParentBase* aBridge,
RefPtr<widget::CompositorWidget>&& aWidget);
RefPtr<widget::CompositorWidget>&& aWidget,
LayoutDeviceIntSize aSize);
wr::WindowId GetId() const { return mId; }
void GenerateFrame();
void SetWindowParameters(LayoutDeviceIntSize size);
void SetRootDisplayList(gfx::Color aBgColor,
Epoch aEpoch,
LayerSize aViewportSize,
@ -56,6 +58,9 @@ public:
uint8_t *aux_data,
size_t aux_size);
void ClearRootDisplayList(Epoch aEpoch,
WrPipelineId pipeline_id);
void SetRootPipeline(wr::PipelineId aPipeline);
void AddImage(wr::ImageKey aKey,
@ -68,8 +73,7 @@ public:
uint64_t aHandle);
void AddExternalImageBuffer(ImageKey key,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
const ImageDescriptor& aDescriptor,
uint64_t aHandle);
void UpdateImageBuffer(wr::ImageKey aKey,
@ -100,6 +104,8 @@ protected:
{}
~WebRenderAPI();
// Should be used only for shutdown handling
void WaitFlushed();
WrAPI* mWrApi;
wr::WindowId mId;
@ -107,6 +113,7 @@ protected:
bool mUseANGLE;
friend class DisplayListBuilder;
friend class layers::WebRenderBridgeParent;
};
/// This is a simple C++ wrapper around WrState defined in the rust bindings.
@ -122,10 +129,7 @@ public:
void Begin(const LayerIntSize& aSize);
void End();
void Finalize(WrBuiltDisplayListDescriptor& dl_descriptor,
wr::VecU8& dl_data,
WrAuxiliaryListsDescriptor& aux_descriptor,
wr::VecU8& aux_data);
wr::BuiltDisplayList Finalize();
void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const WrRect& aOverflow,
@ -136,6 +140,8 @@ public:
void PopStackingContext();
void PushBuiltDisplayList(wr::BuiltDisplayList dl);
void PushScrollLayer(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const WrRect& aOverflow,
const WrImageMask* aMask); // TODO: needs a wrapper.
@ -144,18 +150,18 @@ public:
void PushRect(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrColor& aColor);
void PushLinearGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrPoint& aStartPoint,
const WrPoint& aEndPoint,
const nsTArray<WrGradientStop>& aStops,
wr::GradientExtendMode aExtendMode);
void PushRadialGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrPoint& aStartCenter,
const WrPoint& aEndCenter,
float aStartRadius,
@ -164,32 +170,41 @@ public:
wr::GradientExtendMode aExtendMode);
void PushImage(const WrRect& aBounds,
const WrRect& aClip,
const WrImageMask* aMask,
const WrClipRegion& aClip,
wr::ImageRendering aFilter,
wr::ImageKey aImage);
void PushIFrame(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
wr::PipelineId aPipeline);
void PushBorder(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrBorderWidths& aWidths,
const WrBorderSide& aTop,
const WrBorderSide& aRight,
const WrBorderSide& aBbottom,
const WrBorderSide& aLeft,
const WrBorderRadius& aRadius);
void PushBorderImage(const WrRect& aBounds,
const WrClipRegion& aClip,
const WrBorderWidths& aWidths,
wr::ImageKey aImage,
const WrNinePatchDescriptor& aPatch,
const WrSideOffsets2Df32& aOutset,
const WrRepeatMode& aRepeatHorizontal,
const WrRepeatMode& aRepeatVertical);
void PushText(const WrRect& aBounds,
const WrRect& aClip,
const WrClipRegion& aClip,
const gfx::Color& aColor,
wr::FontKey aFontKey,
Range<const WrGlyphInstance> aGlyphBuffer,
float aGlyphSize);
void PushBoxShadow(const WrRect& aRect,
const WrRect& aClip,
const WrClipRegion& aClip,
const WrRect& aBoxBounds,
const WrPoint& aOffset,
const WrColor& aColor,
@ -198,6 +213,12 @@ public:
const float& aBorderRadius,
const WrBoxShadowClipMode& aClipMode);
WrClipRegion BuildClipRegion(const WrRect& aMain,
const WrImageMask* aMask = nullptr);
WrClipRegion BuildClipRegion(const WrRect& aMain,
const nsTArray<WrComplexClipRegion>& aComplex,
const WrImageMask* aMask = nullptr);
// Try to avoid using this when possible.
WrState* Raw() { return mWrState; }
protected:

Просмотреть файл

@ -177,10 +177,9 @@ static inline WrBorderStyle ToWrBorderStyle(const uint8_t& style)
return WrBorderStyle::None;
}
static inline WrBorderSide ToWrBorderSide(const LayerCoord width, const gfx::Color& color, const uint8_t& style)
static inline WrBorderSide ToWrBorderSide(const gfx::Color& color, const uint8_t& style)
{
WrBorderSide bs;
bs.width = width;
bs.color = ToWrColor(color);
bs.style = ToWrBorderStyle(style);
return bs;
@ -194,9 +193,9 @@ static inline WrPoint ToWrPoint(const LayerPoint point)
return lp;
}
static inline WrLayoutSize ToWrLayoutSize(const LayerSize size)
static inline WrSize ToWrSize(const LayerSize size)
{
WrLayoutSize ls;
WrSize ls;
ls.width = size.width;
ls.height = size.height;
return ls;
@ -206,13 +205,71 @@ static inline WrBorderRadius ToWrBorderRadius(const LayerSize& topLeft, const La
const LayerSize& bottomLeft, const LayerSize& bottomRight)
{
WrBorderRadius br;
br.top_left = ToWrLayoutSize(topLeft);
br.top_right = ToWrLayoutSize(topRight);
br.bottom_left = ToWrLayoutSize(bottomLeft);
br.bottom_right = ToWrLayoutSize(bottomRight);
br.top_left = ToWrSize(topLeft);
br.top_right = ToWrSize(topRight);
br.bottom_left = ToWrSize(bottomLeft);
br.bottom_right = ToWrSize(bottomRight);
return br;
}
static inline WrBorderWidths ToWrBorderWidths(float top, float right, float bottom, float left)
{
WrBorderWidths bw;
bw.top = top;
bw.right = right;
bw.bottom = bottom;
bw.left = left;
return bw;
}
static inline WrNinePatchDescriptor ToWrNinePatchDescriptor(uint32_t width, uint32_t height,
const WrSideOffsets2Du32& slice)
{
WrNinePatchDescriptor patch;
patch.width = width;
patch.height = height;
patch.slice = slice;
return patch;
}
static inline WrSideOffsets2Du32 ToWrSideOffsets2Du32(uint32_t top, uint32_t right, uint32_t bottom, uint32_t left)
{
WrSideOffsets2Du32 offset;
offset.top = top;
offset.right = right;
offset.bottom = bottom;
offset.left = left;
return offset;
}
static inline WrSideOffsets2Df32 ToWrSideOffsets2Df32(float top, float right, float bottom, float left)
{
WrSideOffsets2Df32 offset;
offset.top = top;
offset.right = right;
offset.bottom = bottom;
offset.left = left;
return offset;
}
static inline WrRepeatMode ToWrRepeatMode(uint8_t repeatMode)
{
switch (repeatMode) {
case NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH:
return WrRepeatMode::Stretch;
case NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT:
return WrRepeatMode::Repeat;
case NS_STYLE_BORDER_IMAGE_REPEAT_ROUND:
return WrRepeatMode::Round;
case NS_STYLE_BORDER_IMAGE_REPEAT_SPACE:
return WrRepeatMode::Space;
default:
MOZ_ASSERT(false);
}
return WrRepeatMode::Stretch;
}
template<class T>
static inline WrRect ToWrRect(const gfx::RectTyped<T>& rect)
{
@ -258,6 +315,22 @@ struct VecU8 {
src.inner.capacity = 0;
}
VecU8&
operator=(VecU8&& src) {
inner = src.inner;
src.inner.data = nullptr;
src.inner.capacity = 0;
return *this;
}
WrVecU8
Extract() {
WrVecU8 ret = inner;
inner.data = nullptr;
inner.capacity = 0;
return ret;
}
~VecU8() {
if (inner.data) {
wr_vec_u8_free(inner);

Просмотреть файл

@ -9,6 +9,7 @@ with Files('**'):
EXPORTS.mozilla.webrender += [
'RendererOGL.h',
'RenderTextureHost.h',
'RenderThread.h',
'webrender_ffi.h',
'WebRenderAPI.h',
@ -17,6 +18,7 @@ EXPORTS.mozilla.webrender += [
UNIFIED_SOURCES += [
'RendererOGL.cpp',
'RenderTextureHost.cpp',
'RenderThread.cpp',
'WebRenderAPI.cpp',
]

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -23,6 +23,9 @@ struct WrType { \
bool operator<(const WrType& rhs) const { \
return mHandle < rhs.mHandle; \
} \
bool operator<=(const WrType& rhs) const { \
return mHandle <= rhs.mHandle; \
} \
}; \
// ---
@ -115,14 +118,13 @@ enum class WrImageRendering: uint32_t
Sentinel /* this must be last, for IPC serialization purposes */
};
// TODO(Jerry): handle shmem or cpu raw buffers.
//enum class WrExternalImageIdType: uint32_t
//{
// TextureHandle = 0,
// MemOrShmem = 1,
//
// Sentinel /* this must be last, for IPC serialization purposes */
//};
enum class WrExternalImageIdType: uint32_t
{
NativeTexture, // Currently, we only support gl texture handle.
RawData,
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrMixBlendMode: uint32_t
{
@ -154,6 +156,16 @@ enum class WrGradientExtendMode : uint32_t
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrRepeatMode : uint32_t
{
Stretch = 0,
Repeat = 1,
Round = 2,
Space = 3,
Sentinel /* this must be last, for IPC serialization purposes */
};
// -----
// Typedefs for struct fields and function signatures below.
// -----
@ -164,6 +176,60 @@ typedef uint64_t WrImageIdType;
// Structs used in C++ code with corresponding types in Rust code
// -----
struct WrItemRange
{
size_t start;
size_t length;
};
struct WrBuiltDisplayListDescriptor {
size_t display_list_items_size;
};
struct WrAuxiliaryListsDescriptor {
size_t gradient_stops_size;
size_t complex_clip_regions_size;
size_t filters_size;
size_t glyph_instances_size;
};
struct WrPoint
{
float x;
float y;
bool operator==(const WrPoint& aRhs) const {
return x == aRhs.x && y == aRhs.y;
}
operator mozilla::gfx::Point() const { return mozilla::gfx::Point(x, y); }
};
struct WrSize
{
float width;
float height;
bool operator==(const WrSize& aRhs) const
{
return width == aRhs.width && height == aRhs.height;
}
};
struct WrRect
{
float x;
float y;
float width;
float height;
bool operator==(const WrRect& aRhs) const
{
return x == aRhs.x && y == aRhs.y &&
width == aRhs.width && height == aRhs.height;
}
};
struct WrColor
{
float r;
@ -229,33 +295,20 @@ struct WrGradientStop {
};
struct WrBorderSide {
float width;
WrColor color;
WrBorderStyle style;
bool operator==(const WrBorderSide& aRhs) const
{
return width == aRhs.width && color == aRhs.color &&
style == aRhs.style;
}
};
struct WrLayoutSize
{
float width;
float height;
bool operator==(const WrLayoutSize& aRhs) const
{
return width == aRhs.width && height == aRhs.height;
return color == aRhs.color && style == aRhs.style;
}
};
struct WrBorderRadius {
WrLayoutSize top_left;
WrLayoutSize top_right;
WrLayoutSize bottom_left;
WrLayoutSize bottom_right;
WrSize top_left;
WrSize top_right;
WrSize bottom_left;
WrSize bottom_right;
bool operator==(const WrBorderRadius& aRhs) const
{
@ -264,30 +317,55 @@ struct WrBorderRadius {
}
};
struct WrRect
{
float x;
float y;
float width;
float height;
struct WrBorderWidths {
float left;
float top;
float right;
float bottom;
bool operator==(const WrRect& aRhs) const
bool operator==(const WrBorderWidths& aRhs) const
{
return x == aRhs.x && y == aRhs.y &&
width == aRhs.width && height == aRhs.height;
return left == aRhs.left && top == aRhs.top &&
right == aRhs.right && bottom == aRhs.bottom;
}
};
struct WrPoint
{
float x;
float y;
struct WrSideOffsets2Du32 {
uint32_t top;
uint32_t right;
uint32_t bottom;
uint32_t left;
bool operator==(const WrPoint& aRhs) const {
return x == aRhs.x && y == aRhs.y;
bool operator==(const WrSideOffsets2Du32& aRhs) const
{
return top == aRhs.top && right == aRhs.right &&
bottom == aRhs.bottom && left == aRhs.left;
}
};
operator mozilla::gfx::Point() const { return mozilla::gfx::Point(x, y); }
struct WrSideOffsets2Df32 {
float top;
float right;
float bottom;
float left;
bool operator==(const WrSideOffsets2Df32& aRhs) const
{
return top == aRhs.top && right == aRhs.right &&
bottom == aRhs.bottom && left == aRhs.left;
}
};
struct WrNinePatchDescriptor {
uint32_t width;
uint32_t height;
WrSideOffsets2Du32 slice;
bool operator==(const WrNinePatchDescriptor& aRhs) const
{
return width == aRhs.width && height == aRhs.height &&
slice == aRhs.slice;
}
};
struct WrImageMask
@ -302,6 +380,20 @@ struct WrImageMask
}
};
struct WrComplexClipRegion
{
WrRect rect;
WrBorderRadius radii;
};
struct WrClipRegion
{
WrRect main;
WrItemRange complex;
WrImageMask image_mask;
bool has_image_mask;
};
struct WrExternalImageId
{
WrImageIdType id;
@ -309,7 +401,7 @@ struct WrExternalImageId
struct WrExternalImage
{
//WrExternalImageIdType type;
WrExternalImageIdType type;
// Texture coordinate
float u0, v0;
@ -318,10 +410,9 @@ struct WrExternalImage
// external buffer handle
uint32_t handle;
// TODO(Jerry): handle shmem or cpu raw buffers.
//// shmem or memory buffer
//// uint8_t* buff;
//// size_t size;
// handle RawData.
uint8_t* buff;
size_t size;
};
typedef WrExternalImage (*LockExternalImageCallback)(void*, WrExternalImageId);
@ -344,17 +435,6 @@ struct WrImageDescriptor {
bool is_opaque;
};
struct WrBuiltDisplayListDescriptor {
size_t display_list_items_size;
};
struct WrAuxiliaryListsDescriptor {
size_t gradient_stops_size;
size_t complex_clip_regions_size;
size_t filters_size;
size_t glyph_instances_size;
};
struct WrVecU8 {
uint8_t *data;
size_t length;
@ -401,6 +481,13 @@ WR_INLINE void
wr_renderer_render(WrRenderer* renderer, uint32_t width, uint32_t height)
WR_FUNC;
// It is the responsibility of the caller to manage the dst_buffer memory
// and also free it at the proper time.
WR_INLINE const uint8_t*
wr_renderer_readback(uint32_t width, uint32_t height,
uint8_t* dst_buffer, size_t buffer_length)
WR_FUNC;
WR_INLINE void
wr_renderer_set_profiler_enabled(WrRenderer* renderer, bool enabled)
WR_FUNC;
@ -427,6 +514,8 @@ wr_rendered_epochs_delete(WrRenderedEpochs* pipeline_epochs) WR_DESTRUCTOR_SAFE_
WR_INLINE bool
wr_window_new(WrWindowId window_id,
uint32_t window_width,
uint32_t window_height,
void* aGLContext,
bool enable_profiler,
WrAPI** out_api,
@ -447,8 +536,9 @@ wr_api_add_external_image_handle(WrAPI* api, WrImageKey key, uint32_t width, uin
WR_FUNC;
WR_INLINE void
wr_api_add_external_image_buffer(WrAPI* api, WrImageKey key, uint32_t width, uint32_t height,
WrImageFormat format, uint64_t external_image_id)
wr_api_add_external_image_buffer(WrAPI* api, WrImageKey key,
const WrImageDescriptor* descriptor,
uint64_t external_image_id)
WR_FUNC;
WR_INLINE void
@ -465,6 +555,10 @@ WR_INLINE void
wr_api_set_root_pipeline(WrAPI* api, WrPipelineId pipeline_id)
WR_FUNC;
WR_INLINE void
wr_api_set_window_parameters(WrAPI* api, int width, int height)
WR_FUNC;
WR_INLINE void
wr_api_set_root_display_list(WrAPI* api, WrEpoch epoch, float w, float h,
WrPipelineId pipeline_id,
@ -476,6 +570,10 @@ wr_api_set_root_display_list(WrAPI* api, WrEpoch epoch, float w, float h,
size_t aux_size)
WR_FUNC;
WR_INLINE void
wr_api_clear_root_display_list(WrAPI* api, WrEpoch epoch, WrPipelineId pipeline_id)
WR_FUNC;
WR_INLINE void
wr_api_generate_frame(WrAPI* api)
WR_FUNC;
@ -488,6 +586,10 @@ WR_INLINE void
wr_api_add_raw_font(WrAPI* api, WrFontKey key, uint8_t* font_buffer, size_t buffer_size)
WR_FUNC;
WR_INLINE WrIdNamespace
wr_api_get_namespace(WrAPI* api)
WR_FUNC;
WR_INLINE WrState*
wr_state_new(WrPipelineId pipeline_id)
WR_FUNC;
@ -496,6 +598,21 @@ WR_INLINE void
wr_state_delete(WrState* state)
WR_DESTRUCTOR_SAFE_FUNC;
WR_INLINE void
wr_dp_begin(WrState* wrState, uint32_t width, uint32_t height)
WR_FUNC;
WR_INLINE void
wr_dp_end(WrState* wrState)
WR_FUNC;
WR_INLINE WrClipRegion
wr_dp_new_clip_region(WrState* wrState,
WrRect main,
const WrComplexClipRegion* complex, size_t complexCount,
const WrImageMask* image_mask)
WR_FUNC;
WR_INLINE void
wr_dp_push_stacking_context(WrState *wrState, WrRect bounds,
WrRect overflow, const WrImageMask *mask,
@ -517,41 +634,50 @@ WR_INLINE void
wr_dp_pop_scroll_layer(WrState *wrState)
WR_FUNC;
WR_INLINE void
wr_dp_begin(WrState* wrState, uint32_t width, uint32_t height)
wr_dp_push_iframe(WrState* wrState, WrRect bounds, WrClipRegion clip, WrPipelineId layers_id)
WR_FUNC;
WR_INLINE void
wr_dp_end(WrState* wrState)
WR_FUNC;
WR_INLINE void
wr_dp_push_rect(WrState* wrState, WrRect bounds, WrRect clip,
wr_dp_push_rect(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrColor color)
WR_FUNC;
WR_INLINE void
wr_dp_push_text(WrState* wrState, WrRect bounds, WrRect clip, WrColor color,
wr_dp_push_image(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrImageRendering filter, WrImageKey key)
WR_FUNC;
WR_INLINE void
wr_dp_push_text(WrState* wrState, WrRect bounds, WrClipRegion clip, WrColor color,
WrFontKey font_Key, const WrGlyphInstance* glyphs,
uint32_t glyph_count, float glyph_size)
WR_FUNC;
WR_INLINE void
wr_dp_push_border(WrState* wrState, WrRect bounds, WrRect clip,
wr_dp_push_border(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrBorderWidths widths,
WrBorderSide top, WrBorderSide right, WrBorderSide bottom, WrBorderSide left,
WrBorderRadius radius)
WR_FUNC;
WR_INLINE void
wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrRect clip,
wr_dp_push_border_image(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrBorderWidths widths,
WrImageKey image, WrNinePatchDescriptor patch, WrSideOffsets2Df32 outset,
WrRepeatMode repeat_horizontal,
WrRepeatMode repeat_vertical)
WR_FUNC;
WR_INLINE void
wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrPoint startPoint, WrPoint endPoint,
const WrGradientStop* stops, size_t stopsCount,
WrGradientExtendMode extendMode)
WR_FUNC;
WR_INLINE void
wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrRect clip,
wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrClipRegion clip,
WrPoint startCenter, WrPoint endCenter,
float startRadius, float endRadius,
const WrGradientStop* stops, size_t stopsCount,
@ -559,32 +685,12 @@ wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrRect clip,
WR_FUNC;
WR_INLINE void
wr_dp_push_image(WrState* wrState, WrRect bounds, WrRect clip,
const WrImageMask* mask, WrImageRendering filter, WrImageKey key)
WR_FUNC;
WR_INLINE void
wr_dp_push_iframe(WrState* wrState, WrRect bounds, WrRect clip, WrPipelineId layers_id)
WR_FUNC;
// It is the responsibility of the caller to manage the dst_buffer memory
// and also free it at the proper time.
WR_INLINE const uint8_t*
wr_renderer_readback(uint32_t width, uint32_t height,
uint8_t* dst_buffer, size_t buffer_length)
WR_FUNC;
WR_INLINE void
wr_dp_push_box_shadow(WrState* wrState, WrRect rect, WrRect clip,
wr_dp_push_box_shadow(WrState* wrState, WrRect rect, WrClipRegion clip,
WrRect box_bounds, WrPoint offset, WrColor color,
float blur_radius, float spread_radius, float border_radius,
WrBoxShadowClipMode clip_mode)
WR_FUNC;
WR_INLINE WrIdNamespace
wr_api_get_namespace(WrAPI* api)
WR_FUNC;
WR_INLINE void
wr_api_finalize_builder(WrState* wrState,
WrBuiltDisplayListDescriptor& dl_descriptor,
@ -593,6 +699,14 @@ wr_api_finalize_builder(WrState* wrState,
WrVecU8& aux_data)
WR_FUNC;
WR_INLINE void
wr_dp_push_built_display_list(WrState* wrState,
WrBuiltDisplayListDescriptor dl_descriptor,
WrVecU8 dl_data,
WrAuxiliaryListsDescriptor aux_descriptor,
WrVecU8 aux_data)
WR_FUNC;
WR_INLINE void
wr_vec_u8_free(WrVecU8 dl_data)
WR_FUNC;

Просмотреть файл

@ -1,15 +1,12 @@
[package]
name = "webrender_traits"
version = "0.20.0"
version = "0.25.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
build = "build.rs"
[features]
default = ["codegen"]
nightly = ["euclid/unstable", "serde/unstable"]
codegen = ["serde_codegen", "serde_codegen/with-syntex"]
ipc = ["ipc-channel"]
[dependencies]
@ -21,15 +18,10 @@ heapsize = "0.3.6"
ipc-channel = {version = "0.7", optional = true}
offscreen_gl_context = {version = "0.6", features = ["serde"]}
serde = "0.9"
serde_derive = {version = "0.9", optional = true}
serde_derive = "0.9"
[target.'cfg(target_os = "macos")'.dependencies]
core-graphics = "0.7"
[target.'cfg(target_os = "windows")'.dependencies]
servo-dwrote = "0.2"
[build-dependencies.serde_codegen]
version = "0.9"
default_features = false
optional = true
dwrote = "0.3"

Просмотреть файл

@ -1,46 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[cfg(all(feature = "serde_codegen", not(feature = "serde_derive")))]
mod inner {
extern crate serde_codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let src = Path::new("src/types.rs");
let dst = Path::new(&out_dir).join("types.rs");
serde_codegen::expand(&src, &dst).unwrap();
println!("cargo:rerun-if-changed=src/types.rs");
}
}
#[cfg(all(feature = "serde_derive", not(feature = "serde_codegen")))]
mod inner {
pub fn main() {}
}
#[cfg(all(feature = "serde_codegen", feature = "serde_derive"))]
mod inner {
pub fn main() {
panic!("serde_codegen and serde_derive are both used. \
You probably forgot --no-default-features.")
}
}
#[cfg(not(any(feature = "serde_codegen", feature = "serde_derive")))]
mod inner {
pub fn main() {
panic!("Neither serde_codegen nor serde_derive are used. "
"You probably want --features serde_derive --no-default-features.")
}
}
fn main() {
inner::main();
}

Просмотреть файл

@ -6,16 +6,136 @@ use byteorder::{LittleEndian, WriteBytesExt};
use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use std::cell::Cell;
use {ApiMsg, ColorF, DisplayListBuilder, Epoch, ImageDescriptor};
use {FontKey, IdNamespace, ImageKey, NativeFontHandle, PipelineId};
use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState, ScrollLocation, ServoScrollRootId};
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand, TileSize};
use {DeviceIntSize, DynamicProperties, LayoutPoint, LayoutSize, WorldPoint, PropertyBindingKey, PropertyBindingId};
use {BuiltDisplayList, AuxiliaryLists};
use VRCompositorCommand;
use ExternalEvent;
use {ColorF, ImageDescriptor};
use {FontKey, ImageKey, NativeFontHandle, ServoScrollRootId};
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand};
use {DeviceIntSize, LayoutPoint, LayoutSize, WorldPoint};
use {DeviceIntPoint, DeviceUintRect, DeviceUintSize, LayoutTransform};
use {BuiltDisplayList, BuiltDisplayListDescriptor, AuxiliaryLists, AuxiliaryListsDescriptor};
use std::fmt;
use std::marker::PhantomData;
pub type TileSize = u16;
#[derive(Clone, Deserialize, Serialize)]
pub enum ApiMsg {
AddRawFont(FontKey, Vec<u8>),
AddNativeFont(FontKey, NativeFontHandle),
DeleteFont(FontKey),
/// Gets the glyph dimensions
GetGlyphDimensions(Vec<GlyphKey>, MsgSender<Vec<Option<GlyphDimensions>>>),
/// Adds an image from the resource cache.
AddImage(ImageKey, ImageDescriptor, ImageData, Option<TileSize>),
/// Updates the the resource cache with the new image data.
UpdateImage(ImageKey, ImageDescriptor, Vec<u8>),
/// Drops an image from the resource cache.
DeleteImage(ImageKey),
CloneApi(MsgSender<IdNamespace>),
/// Supplies a new frame to WebRender.
///
/// After receiving this message, WebRender will read the display list, followed by the
/// auxiliary lists, from the payload channel.
SetRootDisplayList(Option<ColorF>,
Epoch,
PipelineId,
LayoutSize,
BuiltDisplayListDescriptor,
AuxiliaryListsDescriptor,
bool),
SetPageZoom(ZoomFactor),
SetPinchZoom(ZoomFactor),
SetPan(DeviceIntPoint),
SetRootPipeline(PipelineId),
SetWindowParameters(DeviceUintSize, DeviceUintRect),
Scroll(ScrollLocation, WorldPoint, ScrollEventPhase),
ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId),
TickScrollingBounce,
TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>),
GetScrollLayerState(MsgSender<Vec<ScrollLayerState>>),
RequestWebGLContext(DeviceIntSize, GLContextAttributes, MsgSender<Result<(WebGLContextId, GLLimits), String>>),
ResizeWebGLContext(WebGLContextId, DeviceIntSize),
WebGLCommand(WebGLContextId, WebGLCommand),
GenerateFrame(Option<DynamicProperties>),
// WebVR commands that must be called in the WebGL render thread.
VRCompositorCommand(WebGLContextId, VRCompositorCommand),
/// An opaque handle that must be passed to the render notifier. It is used by Gecko
/// to forward gecko-specific messages to the render thread preserving the ordering
/// within the other messages.
ExternalEvent(ExternalEvent),
ShutDown,
}
impl fmt::Debug for ApiMsg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&ApiMsg::AddRawFont(..) => { write!(f, "ApiMsg::AddRawFont") }
&ApiMsg::AddNativeFont(..) => { write!(f, "ApiMsg::AddNativeFont") }
&ApiMsg::DeleteFont(..) => { write!(f, "ApiMsg::DeleteFont") }
&ApiMsg::GetGlyphDimensions(..) => { write!(f, "ApiMsg::GetGlyphDimensions") }
&ApiMsg::AddImage(..) => { write!(f, "ApiMsg::AddImage") }
&ApiMsg::UpdateImage(..) => { write!(f, "ApiMsg::UpdateImage") }
&ApiMsg::DeleteImage(..) => { write!(f, "ApiMsg::DeleteImage") }
&ApiMsg::CloneApi(..) => { write!(f, "ApiMsg::CloneApi") }
&ApiMsg::SetRootDisplayList(..) => { write!(f, "ApiMsg::SetRootDisplayList") }
&ApiMsg::SetRootPipeline(..) => { write!(f, "ApiMsg::SetRootPipeline") }
&ApiMsg::Scroll(..) => { write!(f, "ApiMsg::Scroll") }
&ApiMsg::ScrollLayersWithScrollId(..) => { write!(f, "ApiMsg::ScrollLayersWithScrollId") }
&ApiMsg::TickScrollingBounce => { write!(f, "ApiMsg::TickScrollingBounce") }
&ApiMsg::TranslatePointToLayerSpace(..) => { write!(f, "ApiMsg::TranslatePointToLayerSpace") }
&ApiMsg::GetScrollLayerState(..) => { write!(f, "ApiMsg::GetScrollLayerState") }
&ApiMsg::RequestWebGLContext(..) => { write!(f, "ApiMsg::RequestWebGLContext") }
&ApiMsg::ResizeWebGLContext(..) => { write!(f, "ApiMsg::ResizeWebGLContext") }
&ApiMsg::WebGLCommand(..) => { write!(f, "ApiMsg::WebGLCommand") }
&ApiMsg::GenerateFrame(..) => { write!(f, "ApiMsg::GenerateFrame") }
&ApiMsg::VRCompositorCommand(..) => { write!(f, "ApiMsg::VRCompositorCommand") }
&ApiMsg::ExternalEvent(..) => { write!(f, "ApiMsg::ExternalEvent") }
&ApiMsg::ShutDown => { write!(f, "ApiMsg::ShutDown") }
&ApiMsg::SetPageZoom(..) => { write!(f, "ApiMsg::SetPageZoom") }
&ApiMsg::SetPinchZoom(..) => { write!(f, "ApiMsg::SetPinchZoom") }
&ApiMsg::SetPan(..) => { write!(f, "ApiMsg::SetPan") }
&ApiMsg::SetWindowParameters(..) => { write!(f, "ApiMsg::SetWindowParameters") }
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct Epoch(pub u32);
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct PipelineId(pub u32, pub u32);
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct IdNamespace(pub u32);
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct ResourceId(pub u32);
/// An opaque pointer-sized value.
#[repr(C)]
#[derive(Clone, Deserialize, Serialize)]
pub struct ExternalEvent {
raw: usize,
}
unsafe impl Send for ExternalEvent {}
impl ExternalEvent {
pub fn from_raw(raw: usize) -> Self { ExternalEvent { raw: raw } }
/// Consumes self to make it obvious that the event should be forwarded only once.
pub fn unwrap(self) -> usize { self.raw }
}
#[derive(Clone, Deserialize, Serialize)]
pub struct RenderApiSender {
api_sender: MsgSender<ApiMsg>,
payload_sender: PayloadSender,
}
impl RenderApiSender {
pub fn new(api_sender: MsgSender<ApiMsg>,
payload_sender: PayloadSender)
@ -70,6 +190,11 @@ impl RenderApi {
self.api_sender.send(msg).unwrap();
}
pub fn delete_font(&self, key: FontKey) {
let msg = ApiMsg::DeleteFont(key);
self.api_sender.send(msg).unwrap();
}
/// Gets the dimensions for the supplied glyph keys
///
/// Note: Internally, the internal texture cache doesn't store
@ -193,6 +318,28 @@ impl RenderApi {
self.api_sender.send(msg).unwrap();
}
pub fn set_page_zoom(&self, page_zoom: ZoomFactor) {
let msg = ApiMsg::SetPageZoom(page_zoom);
self.api_sender.send(msg).unwrap();
}
pub fn set_pinch_zoom(&self, pinch_zoom: ZoomFactor) {
let msg = ApiMsg::SetPinchZoom(pinch_zoom);
self.api_sender.send(msg).unwrap();
}
pub fn set_pan(&self, pan: DeviceIntPoint) {
let msg = ApiMsg::SetPan(pan);
self.api_sender.send(msg).unwrap();
}
pub fn set_window_parameters(&self,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect) {
let msg = ApiMsg::SetWindowParameters(window_size, inner_rect);
self.api_sender.send(msg).unwrap();
}
pub fn tick_scrolling_bounce_animations(&self) {
let msg = ApiMsg::TickScrollingBounce;
self.api_sender.send(msg).unwrap();
@ -275,3 +422,139 @@ impl RenderApi {
(namespace, id)
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum ScrollEventPhase {
/// The user started scrolling.
Start,
/// The user performed a scroll. The Boolean flag indicates whether the user's fingers are
/// down, if a touchpad is in use. (If false, the event is a touchpad fling.)
Move(bool),
/// The user ended scrolling.
End,
}
#[derive(Clone, Deserialize, Serialize)]
pub struct ScrollLayerState {
pub pipeline_id: PipelineId,
pub scroll_root_id: ServoScrollRootId,
pub scroll_offset: LayoutPoint,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum ScrollLocation {
/// Scroll by a certain amount.
Delta(LayoutPoint),
/// Scroll to very top of element.
Start,
/// Scroll to very bottom of element.
End
}
/// Represents a zoom factor.
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub struct ZoomFactor(f32);
impl ZoomFactor {
/// Construct a new zoom factor.
pub fn new(scale: f32) -> ZoomFactor {
ZoomFactor(scale)
}
/// Get the zoom factor as an untyped float.
pub fn get(&self) -> f32 {
self.0
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Eq, Hash)]
pub struct PropertyBindingId {
namespace: u32,
uid: u32,
}
/// A unique key that is used for connecting animated property
/// values to bindings in the display list.
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PropertyBindingKey<T> {
pub id: PropertyBindingId,
_phantom: PhantomData<T>,
}
/// Construct a property value from a given key and value.
impl<T: Copy> PropertyBindingKey<T> {
pub fn with(&self, value: T) -> PropertyValue<T> {
PropertyValue {
key: *self,
value: value,
}
}
}
/// A binding property can either be a specific value
/// (the normal, non-animated case) or point to a binding location
/// to fetch the current value from.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum PropertyBinding<T> {
Value(T),
Binding(PropertyBindingKey<T>),
}
impl<T> From<T> for PropertyBinding<T> {
fn from(value: T) -> PropertyBinding<T> {
PropertyBinding::Value(value)
}
}
impl<T> From<PropertyBindingKey<T>> for PropertyBinding<T> {
fn from(key: PropertyBindingKey<T>) -> PropertyBinding<T> {
PropertyBinding::Binding(key)
}
}
/// The current value of an animated property. This is
/// supplied by the calling code.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct PropertyValue<T> {
pub key: PropertyBindingKey<T>,
pub value: T,
}
/// When using generate_frame(), a list of PropertyValue structures
/// can optionally be supplied to provide the current value of any
/// animated properties.
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct DynamicProperties {
pub transforms: Vec<PropertyValue<LayoutTransform>>,
pub floats: Vec<PropertyValue<f32>>,
}
pub type VRCompositorId = u64;
// WebVR commands that must be called in the WebGL render thread.
#[derive(Clone, Deserialize, Serialize)]
pub enum VRCompositorCommand {
Create(VRCompositorId),
SyncPoses(VRCompositorId, f64, f64, MsgSender<Result<Vec<u8>,()>>),
SubmitFrame(VRCompositorId, [f32; 4], [f32; 4]),
Release(VRCompositorId)
}
// Trait object that handles WebVR commands.
// Receives the texture_id associated to the WebGLContext.
pub trait VRCompositorHandler: Send {
fn handle(&mut self, command: VRCompositorCommand, texture_id: Option<u32>);
}
pub trait RenderNotifier: Send {
fn new_frame_ready(&mut self);
fn new_scroll_frame_ready(&mut self, composite_needed: bool);
fn external_event(&mut self, _evt: ExternalEvent) { unimplemented!() }
fn shut_down(&mut self) {}
}
// Trait to allow dispatching functions to a specific thread or event loop.
pub trait RenderDispatcher: Send {
fn dispatch(&self, Box<Fn() + Send>);
}

Просмотреть файл

@ -0,0 +1,64 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ColorF {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
known_heap_size!(0, ColorF);
#[repr(C)]
#[derive(Clone, Copy, Hash, Eq, Debug, Deserialize, PartialEq, PartialOrd, Ord, Serialize)]
pub struct ColorU {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl From<ColorF> for ColorU {
fn from(color: ColorF) -> ColorU {
ColorU {
r: ColorU::round_to_int(color.r),
g: ColorU::round_to_int(color.g),
b: ColorU::round_to_int(color.b),
a: ColorU::round_to_int(color.a),
}
}
}
impl Into<ColorF> for ColorU {
fn into(self) -> ColorF {
ColorF {
r: self.r as f32 / 255.0,
g: self.g as f32 / 255.0,
b: self.b as f32 / 255.0,
a: self.a as f32 / 255.0,
}
}
}
impl ColorU {
fn round_to_int(x: f32) -> u8 {
debug_assert!((0.0 <= x) && (x <= 1.0));
let f = (255.0 * x) + 0.5;
let val = f.floor();
debug_assert!(val <= 255.0);
val as u8
}
pub fn new(r: u8, g: u8, b: u8, a: u8) -> ColorU {
ColorU {
r: r,
g: g,
b: b,
a: a,
}
}
}

Просмотреть файл

@ -2,11 +2,379 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use euclid::SideOffsets2D;
use display_list::AuxiliaryListsBuilder;
use {BorderRadius, ClipRegion, ColorF, ComplexClipRegion};
use {FontKey, ImageKey, PipelineId, ScrollLayerId, ScrollLayerInfo, ServoScrollRootId};
use {ImageMask, ItemRange};
use {LayoutSize, LayoutPoint, LayoutRect};
use {ColorF, FontKey, ImageKey, PipelineId, WebGLContextId};
use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
use {PropertyBinding};
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct DisplayItem {
pub item: SpecificDisplayItem,
pub rect: LayoutRect,
pub clip: ClipRegion,
pub scroll_layer_id: ScrollLayerId,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum SpecificDisplayItem {
Clip(ClipDisplayItem),
Rectangle(RectangleDisplayItem),
Text(TextDisplayItem),
Image(ImageDisplayItem),
YuvImage(YuvImageDisplayItem),
WebGL(WebGLDisplayItem),
Border(BorderDisplayItem),
BoxShadow(BoxShadowDisplayItem),
Gradient(GradientDisplayItem),
RadialGradient(RadialGradientDisplayItem),
Iframe(IframeDisplayItem),
PushStackingContext(PushStackingContextDisplayItem),
PopStackingContext,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ItemRange {
pub start: usize,
pub length: usize,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ClipDisplayItem {
pub content_size: LayoutSize,
pub id: ScrollLayerId,
pub parent_id: ScrollLayerId,
pub scroll_root_id: Option<ServoScrollRootId>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RectangleDisplayItem {
pub color: ColorF,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct TextDisplayItem {
pub glyphs: ItemRange,
pub font_key: FontKey,
pub size: Au,
pub color: ColorF,
pub blur_radius: Au,
pub glyph_options: Option<GlyphOptions>,
}
#[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
pub struct GlyphOptions {
// These are currently only used on windows for dwrite fonts.
pub use_embedded_bitmap: bool,
pub force_gdi_rendering: bool,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct WebGLDisplayItem {
pub context_id: WebGLContextId,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct NormalBorder {
pub left: BorderSide,
pub right: BorderSide,
pub top: BorderSide,
pub bottom: BorderSide,
pub radius: BorderRadius,
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum RepeatMode {
Stretch,
Repeat,
Round,
Space,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct NinePatchDescriptor {
pub width: u32,
pub height: u32,
pub slice: SideOffsets2D<u32>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageBorder {
pub image_key: ImageKey,
pub patch: NinePatchDescriptor,
pub outset: SideOffsets2D<f32>,
pub repeat_horizontal: RepeatMode,
pub repeat_vertical: RepeatMode,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GradientBorder {
pub gradient: Gradient,
pub outset: SideOffsets2D<f32>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RadialGradientBorder {
pub gradient: RadialGradient,
pub outset: SideOffsets2D<f32>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum BorderDetails {
Normal(NormalBorder),
Image(ImageBorder),
Gradient(GradientBorder),
RadialGradient(RadialGradientBorder),
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderDisplayItem {
pub widths: BorderWidths,
pub details: BorderDetails,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderRadius {
pub top_left: LayoutSize,
pub top_right: LayoutSize,
pub bottom_left: LayoutSize,
pub bottom_right: LayoutSize,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderWidths {
pub left: f32,
pub top: f32,
pub right: f32,
pub bottom: f32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderSide {
pub color: ColorF,
pub style: BorderStyle,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum BorderStyle {
None = 0,
Solid = 1,
Double = 2,
Dotted = 3,
Dashed = 4,
Hidden = 5,
Groove = 6,
Ridge = 7,
Inset = 8,
Outset = 9,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum BoxShadowClipMode {
None = 0,
Outset = 1,
Inset = 2,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BoxShadowDisplayItem {
pub box_bounds: LayoutRect,
pub offset: LayoutPoint,
pub color: ColorF,
pub blur_radius: f32,
pub spread_radius: f32,
pub border_radius: f32,
pub clip_mode: BoxShadowClipMode,
}
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ExtendMode {
Clamp,
Repeat,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct Gradient {
pub start_point: LayoutPoint,
pub end_point: LayoutPoint,
pub stops: ItemRange,
pub extend_mode: ExtendMode,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GradientDisplayItem {
pub gradient: Gradient,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GradientStop {
pub offset: f32,
pub color: ColorF,
}
known_heap_size!(0, GradientStop);
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RadialGradient {
pub start_center: LayoutPoint,
pub start_radius: f32,
pub end_center: LayoutPoint,
pub end_radius: f32,
pub stops: ItemRange,
pub extend_mode: ExtendMode,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RadialGradientDisplayItem {
pub gradient: RadialGradient,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PushStackingContextDisplayItem {
pub stacking_context: StackingContext,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct StackingContext {
pub scroll_policy: ScrollPolicy,
pub bounds: LayoutRect,
pub z_index: i32,
pub transform: Option<PropertyBinding<LayoutTransform>>,
pub perspective: Option<LayoutTransform>,
pub mix_blend_mode: MixBlendMode,
pub filters: ItemRange,
}
#[repr(C)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ScrollPolicy {
Scrollable = 0,
Fixed = 1,
}
known_heap_size!(0, ScrollPolicy);
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum MixBlendMode {
Normal = 0,
Multiply = 1,
Screen = 2,
Overlay = 3,
Darken = 4,
Lighten = 5,
ColorDodge = 6,
ColorBurn = 7,
HardLight = 8,
SoftLight = 9,
Difference = 10,
Exclusion = 11,
Hue = 12,
Saturation = 13,
Color = 14,
Luminosity = 15,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum FilterOp {
Blur(Au),
Brightness(f32),
Contrast(f32),
Grayscale(f32),
HueRotate(f32),
Invert(f32),
Opacity(PropertyBinding<f32>),
Saturate(f32),
Sepia(f32),
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct IframeDisplayItem {
pub pipeline_id: PipelineId,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageDisplayItem {
pub image_key: ImageKey,
pub stretch_size: LayoutSize,
pub tile_spacing: LayoutSize,
pub image_rendering: ImageRendering,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ImageRendering {
Auto = 0,
CrispEdges = 1,
Pixelated = 2,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct YuvImageDisplayItem {
pub y_image_key: ImageKey,
pub u_image_key: ImageKey,
pub v_image_key: ImageKey,
pub color_space: YuvColorSpace,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum YuvColorSpace {
Rec601 = 1, // The values must match the ones in prim_shared.glsl
Rec709 = 2,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageMask {
pub image: ImageKey,
pub rect: LayoutRect,
pub repeat: bool,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ClipRegion {
pub main: LayoutRect,
pub complex: ItemRange,
pub image_mask: Option<ImageMask>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ComplexClipRegion {
/// The boundaries of the rectangle.
pub rect: LayoutRect,
/// Border radii of this rectangle.
pub radii: BorderRadius,
}
impl StackingContext {
pub fn new(scroll_policy: ScrollPolicy,
bounds: LayoutRect,
z_index: i32,
transform: Option<PropertyBinding<LayoutTransform>>,
perspective: Option<LayoutTransform>,
mix_blend_mode: MixBlendMode,
filters: Vec<FilterOp>,
auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
-> StackingContext {
StackingContext {
scroll_policy: scroll_policy,
bounds: bounds,
z_index: z_index,
transform: transform,
perspective: perspective,
mix_blend_mode: mix_blend_mode,
filters: auxiliary_lists_builder.add_filters(&filters),
}
}
}
impl BorderRadius {
pub fn zero() -> BorderRadius {
@ -141,26 +509,48 @@ impl ComplexClipRegion {
}
}
impl FontKey {
pub fn new(key0: u32, key1: u32) -> FontKey {
FontKey(key0, key1)
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ServoScrollRootId(pub usize);
impl ImageKey {
pub fn new(key0: u32, key1: u32) -> ImageKey {
ImageKey(key0, key1)
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ScrollLayerId {
pub pipeline_id: PipelineId,
pub info: ScrollLayerInfo,
}
impl ScrollLayerId {
pub fn new(pipeline_id: PipelineId,
index: usize,
scroll_root_id: ServoScrollRootId)
-> ScrollLayerId {
pub fn root_scroll_layer(pipeline_id: PipelineId) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::Scrollable(index, scroll_root_id),
info: ScrollLayerInfo::Scrollable(0),
}
}
pub fn root_reference_frame(pipeline_id: PipelineId) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::ReferenceFrame(0),
}
}
pub fn is_reference_frame(&self) -> bool {
match self.info {
ScrollLayerInfo::Scrollable(..) => false,
ScrollLayerInfo::ReferenceFrame(..) => true,
}
}
pub fn new(pipeline_id: PipelineId, index: usize) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::Scrollable(index),
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ScrollLayerInfo {
Scrollable(usize),
ReferenceFrame(usize),
}

Просмотреть файл

@ -5,17 +5,54 @@
use app_units::Au;
use std::mem;
use std::slice;
use {AuxiliaryLists, AuxiliaryListsDescriptor, BorderDisplayItem};
use {BoxShadowClipMode, BoxShadowDisplayItem, BuiltDisplayList};
use {BuiltDisplayListDescriptor, ClipRegion, ComplexClipRegion, ColorF};
use {DisplayItem, ExtendMode, FilterOp, YuvColorSpace};
use {FontKey, GlyphInstance, GradientDisplayItem, RadialGradientDisplayItem, GradientStop, IframeDisplayItem};
use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange, MixBlendMode, PipelineId};
use {PushScrollLayerItem, PushStackingContextDisplayItem, RectangleDisplayItem, ScrollLayerId};
use {ScrollPolicy, ServoScrollRootId, SpecificDisplayItem, StackingContext, TextDisplayItem};
use {WebGLContextId, WebGLDisplayItem, YuvImageDisplayItem};
use {LayoutTransform, LayoutPoint, LayoutRect, LayoutSize};
use {BorderDetails, BorderWidths, GlyphOptions, PropertyBinding};
use {BorderDetails, BorderDisplayItem, BorderWidths, BoxShadowClipMode, BoxShadowDisplayItem};
use {ClipDisplayItem, ClipRegion, ColorF, ComplexClipRegion, DisplayItem, ExtendMode, FilterOp};
use {FontKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, GradientStop};
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange};
use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode, PipelineId};
use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem};
use {StackingContext, TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace};
use YuvImageDisplayItem;
#[derive(Clone, Deserialize, Serialize)]
pub struct AuxiliaryLists {
/// The concatenation of: gradient stops, complex clip regions, filters, and glyph instances,
/// in that order.
data: Vec<u8>,
descriptor: AuxiliaryListsDescriptor,
}
/// Describes the memory layout of the auxiliary lists.
///
/// Auxiliary lists consist of some number of gradient stops, complex clip regions, filters, and
/// glyph instances, in that order.
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct AuxiliaryListsDescriptor {
gradient_stops_size: usize,
complex_clip_regions_size: usize,
filters_size: usize,
glyph_instances_size: usize,
}
/// A display list.
#[derive(Clone, Deserialize, Serialize)]
pub struct BuiltDisplayList {
data: Vec<u8>,
descriptor: BuiltDisplayListDescriptor,
}
/// Describes the memory layout of a display list.
///
/// A display list consists of some number of display list items, followed by a number of display
/// items.
#[repr(C)]
#[derive(Copy, Clone, Deserialize, Serialize)]
pub struct BuiltDisplayListDescriptor {
/// The size in bytes of the display list items in this display list.
display_list_items_size: usize,
}
impl BuiltDisplayListDescriptor {
pub fn size(&self) -> usize {
@ -51,6 +88,7 @@ pub struct DisplayListBuilder {
pub list: Vec<DisplayItem>,
auxiliary_lists_builder: AuxiliaryListsBuilder,
pub pipeline_id: PipelineId,
clip_stack: Vec<ScrollLayerId>,
next_scroll_layer_id: usize,
}
@ -60,7 +98,10 @@ impl DisplayListBuilder {
list: Vec::new(),
auxiliary_lists_builder: AuxiliaryListsBuilder::new(),
pipeline_id: pipeline_id,
next_scroll_layer_id: 0,
clip_stack: vec![ScrollLayerId::root_scroll_layer(pipeline_id)],
// We start at 1 here, because the root scroll id is always 0.
next_scroll_layer_id: 1,
}
}
@ -70,21 +111,33 @@ impl DisplayListBuilder {
}
}
fn push_item(&mut self, item: SpecificDisplayItem, rect: LayoutRect, clip: ClipRegion) {
self.list.push(DisplayItem {
item: item,
rect: rect,
clip: clip,
scroll_layer_id: *self.clip_stack.last().unwrap(),
});
}
fn push_new_empty_item(&mut self, item: SpecificDisplayItem) {
self.list.push(DisplayItem {
item: item,
rect: LayoutRect::zero(),
clip: ClipRegion::simple(&LayoutRect::zero()),
scroll_layer_id: *self.clip_stack.last().unwrap(),
});
}
pub fn push_rect(&mut self,
rect: LayoutRect,
clip: ClipRegion,
color: ColorF) {
let item = RectangleDisplayItem {
let item = SpecificDisplayItem::Rectangle(RectangleDisplayItem {
color: color,
};
});
let display_item = DisplayItem {
item: SpecificDisplayItem::Rectangle(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_image(&mut self,
@ -94,20 +147,14 @@ impl DisplayListBuilder {
tile_spacing: LayoutSize,
image_rendering: ImageRendering,
key: ImageKey) {
let item = ImageDisplayItem {
let item = SpecificDisplayItem::Image(ImageDisplayItem {
image_key: key,
stretch_size: stretch_size,
tile_spacing: tile_spacing,
image_rendering: image_rendering,
};
});
let display_item = DisplayItem {
item: SpecificDisplayItem::Image(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_yuv_image(&mut self,
@ -117,33 +164,23 @@ impl DisplayListBuilder {
u_key: ImageKey,
v_key: ImageKey,
color_space: YuvColorSpace) {
self.list.push(DisplayItem {
item: SpecificDisplayItem::YuvImage(YuvImageDisplayItem {
let item = SpecificDisplayItem::YuvImage(YuvImageDisplayItem {
y_image_key: y_key,
u_image_key: u_key,
v_image_key: v_key,
color_space: color_space,
}),
rect: rect,
clip: clip,
});
self.push_item(item, rect, clip);
}
pub fn push_webgl_canvas(&mut self,
rect: LayoutRect,
clip: ClipRegion,
context_id: WebGLContextId) {
let item = WebGLDisplayItem {
let item = SpecificDisplayItem::WebGL(WebGLDisplayItem {
context_id: context_id,
};
let display_item = DisplayItem {
item: SpecificDisplayItem::WebGL(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
});
self.push_item(item, rect, clip);
}
pub fn push_text(&mut self,
@ -162,22 +199,46 @@ impl DisplayListBuilder {
// font as a crash test - the rendering is also ignored
// by the azure renderer.
if size < Au::from_px(4096) {
let item = TextDisplayItem {
let item = SpecificDisplayItem::Text(TextDisplayItem {
color: color,
glyphs: self.auxiliary_lists_builder.add_glyph_instances(&glyphs),
font_key: font_key,
size: size,
blur_radius: blur_radius,
glyph_options: glyph_options,
};
});
let display_item = DisplayItem {
item: SpecificDisplayItem::Text(item),
rect: rect,
clip: clip,
};
self.push_item(item, rect, clip);
}
}
self.list.push(display_item);
pub fn create_gradient(&mut self,
start_point: LayoutPoint,
end_point: LayoutPoint,
stops: Vec<GradientStop>,
extend_mode: ExtendMode) -> Gradient {
Gradient {
start_point: start_point,
end_point: end_point,
stops: self.auxiliary_lists_builder.add_gradient_stops(&stops),
extend_mode: extend_mode,
}
}
pub fn create_radial_gradient(&mut self,
start_center: LayoutPoint,
start_radius: f32,
end_center: LayoutPoint,
end_radius: f32,
stops: Vec<GradientStop>,
extend_mode: ExtendMode) -> RadialGradient {
RadialGradient {
start_center: start_center,
start_radius: start_radius,
end_center: end_center,
end_radius: end_radius,
stops: self.auxiliary_lists_builder.add_gradient_stops(&stops),
extend_mode: extend_mode,
}
}
@ -186,18 +247,12 @@ impl DisplayListBuilder {
clip: ClipRegion,
widths: BorderWidths,
details: BorderDetails) {
let item = BorderDisplayItem {
let item = SpecificDisplayItem::Border(BorderDisplayItem {
details: details,
widths: widths,
};
});
let display_item = DisplayItem {
item: SpecificDisplayItem::Border(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_box_shadow(&mut self,
@ -210,7 +265,7 @@ impl DisplayListBuilder {
spread_radius: f32,
border_radius: f32,
clip_mode: BoxShadowClipMode) {
let item = BoxShadowDisplayItem {
let item = SpecificDisplayItem::BoxShadow(BoxShadowDisplayItem {
box_bounds: box_bounds,
offset: offset,
color: color,
@ -218,15 +273,9 @@ impl DisplayListBuilder {
spread_radius: spread_radius,
border_radius: border_radius,
clip_mode: clip_mode,
};
});
let display_item = DisplayItem {
item: SpecificDisplayItem::BoxShadow(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_gradient(&mut self,
@ -236,20 +285,11 @@ impl DisplayListBuilder {
end_point: LayoutPoint,
stops: Vec<GradientStop>,
extend_mode: ExtendMode) {
let item = GradientDisplayItem {
start_point: start_point,
end_point: end_point,
stops: self.auxiliary_lists_builder.add_gradient_stops(&stops),
extend_mode: extend_mode,
};
let item = SpecificDisplayItem::Gradient(GradientDisplayItem {
gradient: self.create_gradient(start_point, end_point, stops, extend_mode),
});
let display_item = DisplayItem {
item: SpecificDisplayItem::Gradient(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_radial_gradient(&mut self,
@ -261,22 +301,13 @@ impl DisplayListBuilder {
end_radius: f32,
stops: Vec<GradientStop>,
extend_mode: ExtendMode) {
let item = RadialGradientDisplayItem {
start_center: start_center,
start_radius: start_radius,
end_center: end_center,
end_radius: end_radius,
stops: self.auxiliary_lists_builder.add_gradient_stops(&stops),
extend_mode: extend_mode,
};
let item = SpecificDisplayItem::RadialGradient(RadialGradientDisplayItem {
gradient: self.create_radial_gradient(start_center, start_radius,
end_center, end_radius,
stops, extend_mode),
});
let display_item = DisplayItem {
item: SpecificDisplayItem::RadialGradient(item),
rect: rect,
clip: clip,
};
self.list.push(display_item);
self.push_item(item, rect, clip);
}
pub fn push_stacking_context(&mut self,
@ -284,75 +315,107 @@ impl DisplayListBuilder {
bounds: LayoutRect,
clip: ClipRegion,
z_index: i32,
transform: PropertyBinding<LayoutTransform>,
perspective: LayoutTransform,
transform: Option<PropertyBinding<LayoutTransform>>,
perspective: Option<LayoutTransform>,
mix_blend_mode: MixBlendMode,
filters: Vec<FilterOp>) {
let stacking_context = StackingContext {
scroll_policy: scroll_policy,
bounds: bounds,
z_index: z_index,
transform: transform,
perspective: perspective,
mix_blend_mode: mix_blend_mode,
filters: self.auxiliary_lists_builder.add_filters(&filters),
};
let item = SpecificDisplayItem::PushStackingContext(PushStackingContextDisplayItem {
stacking_context: StackingContext {
scroll_policy: scroll_policy,
bounds: bounds,
z_index: z_index,
transform: transform,
perspective: perspective,
mix_blend_mode: mix_blend_mode,
filters: self.auxiliary_lists_builder.add_filters(&filters),
}
});
let item = DisplayItem {
item: SpecificDisplayItem::PushStackingContext(PushStackingContextDisplayItem {
stacking_context: stacking_context
}),
rect: LayoutRect::zero(),
clip: clip,
};
self.list.push(item);
self.push_item(item, LayoutRect::zero(), clip);
}
pub fn pop_stacking_context(&mut self) {
let item = DisplayItem {
item: SpecificDisplayItem::PopStackingContext,
rect: LayoutRect::zero(),
clip: ClipRegion::simple(&LayoutRect::zero()),
};
self.list.push(item);
self.push_new_empty_item(SpecificDisplayItem::PopStackingContext);
}
pub fn define_clip(&mut self,
clip: ClipRegion,
content_size: LayoutSize,
scroll_root_id: Option<ServoScrollRootId>)
-> ScrollLayerId {
let scroll_layer_id = self.next_scroll_layer_id;
self.next_scroll_layer_id += 1;
let id = ScrollLayerId::new(self.pipeline_id, scroll_layer_id);
let item = SpecificDisplayItem::Clip(ClipDisplayItem {
content_size: content_size,
id: id,
parent_id: *self.clip_stack.last().unwrap(),
scroll_root_id: scroll_root_id,
});
self.push_item(item, clip.main, clip);
id
}
pub fn push_scroll_layer(&mut self,
clip: ClipRegion,
content_size: LayoutSize,
scroll_root_id: ServoScrollRootId) {
let scroll_layer_id = self.next_scroll_layer_id;
self.next_scroll_layer_id += 1;
scroll_root_id: Option<ServoScrollRootId>) {
let id = self.define_clip(clip, content_size, scroll_root_id);
self.clip_stack.push(id);
}
let item = PushScrollLayerItem {
content_size: content_size,
id: ScrollLayerId::new(self.pipeline_id, scroll_layer_id, scroll_root_id),
};
pub fn push_clip_id(&mut self, id: ScrollLayerId) {
self.clip_stack.push(id);
}
let item = DisplayItem {
item: SpecificDisplayItem::PushScrollLayer(item),
rect: clip.main,
clip: clip,
};
self.list.push(item);
pub fn pop_clip_id(&mut self) {
self.clip_stack.pop();
assert!(self.clip_stack.len() > 0);
}
pub fn pop_scroll_layer(&mut self) {
let item = DisplayItem {
item: SpecificDisplayItem::PopScrollLayer,
rect: LayoutRect::zero(),
clip: ClipRegion::simple(&LayoutRect::zero()),
};
self.list.push(item);
self.pop_clip_id();
}
pub fn push_iframe(&mut self, rect: LayoutRect, clip: ClipRegion, pipeline_id: PipelineId) {
let item = DisplayItem {
item: SpecificDisplayItem::Iframe(IframeDisplayItem { pipeline_id: pipeline_id }),
rect: rect,
clip: clip,
};
self.list.push(item);
let item = SpecificDisplayItem::Iframe(IframeDisplayItem { pipeline_id: pipeline_id });
self.push_item(item, rect, clip);
}
// Don't use this function. It will go away.
// We're using it as a hack in Gecko to retain parts sub-parts of display lists so that
// we can regenerate them without building Gecko display items.
pub fn push_built_display_list(&mut self, dl: BuiltDisplayList, aux: AuxiliaryLists) {
use SpecificDisplayItem::*;
// It's important for us to make sure that all of ItemRange structures are relocated
// when copying from one list to another. To avoid this problem we could use a custom
// derive implementation that would let ItemRanges relocate themselves.
for i in dl.all_display_items() {
let mut i = *i;
match i.item {
Text(ref mut item) => {
item.glyphs = self.auxiliary_lists_builder.add_glyph_instances(aux.glyph_instances(&item.glyphs));
}
Gradient(ref mut item) => {
item.gradient.stops = self.auxiliary_lists_builder.add_gradient_stops(aux.gradient_stops(&item.gradient.stops));
}
RadialGradient(ref mut item) => {
item.gradient.stops = self.auxiliary_lists_builder.add_gradient_stops(aux.gradient_stops(&item.gradient.stops));
}
PushStackingContext(ref mut item) => {
item.stacking_context.filters = self.auxiliary_lists_builder.add_filters(aux.filters(&item.stacking_context.filters));
}
Iframe(_) | Clip(_) => {
// We don't support relocating these
panic!();
}
_ => {}
}
i.clip.complex = self.auxiliary_lists_builder.add_complex_clip_regions(aux.complex_clip_regions(&i.clip.complex));
self.list.push(i);
}
}
pub fn new_clip_region(&mut self,

Просмотреть файл

@ -0,0 +1,152 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use euclid::Point2D;
use {ColorU, ColorF};
#[cfg(target_os = "macos")] use core_graphics::font::CGFont;
#[cfg(target_os = "windows")] use dwrote::FontDescriptor;
#[cfg(target_os = "macos")]
pub type NativeFontHandle = CGFont;
/// Native fonts are not used on Linux; all fonts are raw.
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[cfg_attr(not(any(target_os = "macos", target_os = "windows")), derive(Clone, Serialize, Deserialize))]
pub struct NativeFontHandle;
#[cfg(target_os = "windows")]
pub type NativeFontHandle = FontDescriptor;
#[repr(C)]
#[derive(Copy, Clone, Deserialize, Serialize, Debug)]
pub struct GlyphDimensions {
pub left: i32,
pub top: i32,
pub width: u32,
pub height: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, Ord, PartialOrd)]
pub struct FontKey(pub u32, pub u32);
impl FontKey {
pub fn new(key0: u32, key1: u32) -> FontKey {
FontKey(key0, key1)
}
}
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum FontRenderMode {
Mono,
Alpha,
Subpixel,
}
impl FontRenderMode {
// Skia quantizes subpixel offets into 1/4 increments.
// Given the absolute position, return the quantized increment
fn subpixel_quantize_offset(&self, pos: f32) -> SubpixelOffset {
if *self != FontRenderMode::Subpixel {
return SubpixelOffset::Zero;
}
const SUBPIXEL_ROUNDING :f32 = 0.125; // Skia chosen value.
let fraction = (pos + SUBPIXEL_ROUNDING).fract();
match fraction {
0.0...0.25 => SubpixelOffset::Zero,
0.25...0.5 => SubpixelOffset::Quarter,
0.5...0.75 => SubpixelOffset::Half,
0.75...1.0 => SubpixelOffset::ThreeQuarters,
_ => panic!("Should only be given the fractional part"),
}
}
}
#[repr(u8)]
#[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum SubpixelOffset {
Zero = 0,
Quarter = 1,
Half = 2,
ThreeQuarters = 3,
}
impl Into<f64> for SubpixelOffset {
fn into(self) -> f64 {
match self {
SubpixelOffset::Zero => 0.0,
SubpixelOffset::Quarter => 0.25,
SubpixelOffset::Half => 0.5,
SubpixelOffset::ThreeQuarters => 0.75,
}
}
}
#[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)]
pub struct SubpixelPoint {
pub x: SubpixelOffset,
pub y: SubpixelOffset,
}
impl SubpixelPoint {
pub fn new(point: Point2D<f32>,
render_mode: FontRenderMode) -> SubpixelPoint {
SubpixelPoint {
x: render_mode.subpixel_quantize_offset(point.x),
y: render_mode.subpixel_quantize_offset(point.y),
}
}
pub fn to_f64(&self) -> (f64, f64) {
return (self.x.into(), self.y.into());
}
pub fn set_offset(&mut self, point: Point2D<f32>, render_mode: FontRenderMode) {
self.x = render_mode.subpixel_quantize_offset(point.x);
self.y = render_mode.subpixel_quantize_offset(point.y);
}
}
#[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)]
pub struct GlyphKey {
pub font_key: FontKey,
// The font size is in *device* pixels, not logical pixels.
// It is stored as an Au since we need sub-pixel sizes, but
// can't store as a f32 due to use of this type as a hash key.
// TODO(gw): Perhaps consider having LogicalAu and DeviceAu
// or something similar to that.
pub size: Au,
pub index: u32,
pub color: ColorU,
pub subpixel_point: SubpixelPoint,
}
impl GlyphKey {
pub fn new(font_key: FontKey,
size: Au,
color: ColorF,
index: u32,
point: Point2D<f32>,
render_mode: FontRenderMode) -> GlyphKey {
GlyphKey {
font_key: font_key,
size: size,
color: ColorU::from(color),
index: index,
subpixel_point: SubpixelPoint::new(point, render_mode),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GlyphInstance {
pub index: u32,
pub point: Point2D<f32>,
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше