diff --git a/README.webrender b/README.webrender index 14481370573e..7f892c68dc33 100644 --- a/README.webrender +++ b/README.webrender @@ -48,4 +48,4 @@ graphics branch Yes, this is somewhat painful. It used to be worse. :) -Latest Commit: 996f2ba9da276ac813a6c0dec67339769f1264db +Latest Commit: 9839014c9a7269494fb40c1300f9e686738d42a3 diff --git a/gfx/webrender/Cargo.toml b/gfx/webrender/Cargo.toml index 83ccc2672431..bf9b8417e299 100644 --- a/gfx/webrender/Cargo.toml +++ b/gfx/webrender/Cargo.toml @@ -18,9 +18,9 @@ app_units = "0.3" bincode = "0.6" bit-set = "0.4" byteorder = "0.5" -euclid = "0.10" +euclid = "0.10.3" fnv="1.0" -gleam = "0.2.25" +gleam = "0.2.29" lazy_static = "0.2" log = "0.3" num-traits = "0.1.32" diff --git a/gfx/webrender/res/clip_shared.glsl b/gfx/webrender/res/clip_shared.glsl index a86a3602b31c..35f13fdffb2b 100644 --- a/gfx/webrender/res/clip_shared.glsl +++ b/gfx/webrender/res/clip_shared.glsl @@ -5,6 +5,11 @@ #ifdef WR_VERTEX_SHADER +in int aClipRenderTaskIndex; +in int aClipLayerIndex; +in int aClipDataIndex; +in int aClipBaseTaskIndex; + struct CacheClipInstance { int render_task_index; int layer_index; @@ -15,14 +20,10 @@ struct CacheClipInstance { CacheClipInstance fetch_clip_item(int index) { CacheClipInstance cci; - int offset = index * 1; - - ivec4 data0 = int_data[offset + 0]; - - cci.render_task_index = data0.x; - cci.layer_index = data0.y; - cci.data_index = data0.z; - cci.base_task_index = data0.w; + cci.render_task_index = aClipRenderTaskIndex; + cci.layer_index = aClipLayerIndex; + cci.data_index = aClipDataIndex; + cci.base_task_index = aClipBaseTaskIndex; return cci; } diff --git a/gfx/webrender/res/cs_blur.fs.glsl b/gfx/webrender/res/cs_blur.fs.glsl index 4217b780f2e8..550e42f5d237 100644 --- a/gfx/webrender/res/cs_blur.fs.glsl +++ b/gfx/webrender/res/cs_blur.fs.glsl @@ -15,8 +15,8 @@ float gauss(float x, float sigma) { } void main(void) { - vec4 sample = texture(sCache, vUv); - vec4 color = vec4(sample.rgb * sample.a, sample.a) * gauss(0.0, vSigma); + vec4 cache_sample = texture(sCache, vUv); + vec4 color = vec4(cache_sample.rgb, 1.0) * (cache_sample.a * gauss(0.0, vSigma)); for (int i=1 ; i < vBlurRadius ; ++i) { vec2 offset = vec2(float(i)) * vOffsetScale; diff --git a/gfx/webrender/res/cs_blur.vs.glsl b/gfx/webrender/res/cs_blur.vs.glsl index 1e89b60e5e54..edb0f5fdc602 100644 --- a/gfx/webrender/res/cs_blur.vs.glsl +++ b/gfx/webrender/res/cs_blur.vs.glsl @@ -9,8 +9,28 @@ #define DIR_HORIZONTAL 0 #define DIR_VERTICAL 1 +in int aBlurRenderTaskIndex; +in int aBlurSourceTaskIndex; +in int aBlurDirection; + +struct BlurCommand { + int task_id; + int src_task_id; + int dir; +}; + +BlurCommand fetch_blur() { + BlurCommand blur; + + blur.task_id = aBlurRenderTaskIndex; + blur.src_task_id = aBlurSourceTaskIndex; + blur.dir = aBlurDirection; + + return blur; +} + void main(void) { - BlurCommand cmd = fetch_blur(gl_InstanceID); + BlurCommand cmd = fetch_blur(); RenderTaskData task = fetch_render_task(cmd.task_id); RenderTaskData src_task = fetch_render_task(cmd.src_task_id); @@ -20,7 +40,7 @@ void main(void) { local_rect.xy + local_rect.zw, aPosition.xy); - vec2 texture_size = textureSize(sCache, 0).xy; + vec2 texture_size = vec2(textureSize(sCache, 0).xy); vUv.z = src_task.data1.x; vBlurRadius = int(task.data1.y); vSigma = task.data1.y * 0.5; diff --git a/gfx/webrender/res/cs_box_shadow.vs.glsl b/gfx/webrender/res/cs_box_shadow.vs.glsl index fce6e53af1d6..a9bb8abdf22a 100644 --- a/gfx/webrender/res/cs_box_shadow.vs.glsl +++ b/gfx/webrender/res/cs_box_shadow.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - CachePrimitiveInstance cpi = fetch_cache_instance(gl_InstanceID); + CachePrimitiveInstance cpi = fetch_cache_instance(); RenderTaskData task = fetch_render_task(cpi.render_task_index); BoxShadow bs = fetch_boxshadow(cpi.specific_prim_index); diff --git a/gfx/webrender/res/cs_text_run.vs.glsl b/gfx/webrender/res/cs_text_run.vs.glsl index 46703a0d09e7..07c269e224b0 100644 --- a/gfx/webrender/res/cs_text_run.vs.glsl +++ b/gfx/webrender/res/cs_text_run.vs.glsl @@ -8,7 +8,7 @@ // as text-shadow. void main(void) { - CachePrimitiveInstance cpi = fetch_cache_instance(gl_InstanceID); + CachePrimitiveInstance cpi = fetch_cache_instance(); RenderTaskData task = fetch_render_task(cpi.render_task_index); TextRun text = fetch_text_run(cpi.specific_prim_index); Glyph glyph = fetch_glyph(cpi.sub_index); diff --git a/gfx/webrender/res/debug_color.fs.glsl b/gfx/webrender/res/debug_color.fs.glsl index e9aae6413820..f9f3425e951b 100644 --- a/gfx/webrender/res/debug_color.fs.glsl +++ b/gfx/webrender/res/debug_color.fs.glsl @@ -2,6 +2,8 @@ * 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/. */ +varying vec4 vColor; + void main(void) { oFragColor = vColor; diff --git a/gfx/webrender/res/debug_color.vs.glsl b/gfx/webrender/res/debug_color.vs.glsl index 78e7a306c206..800b5628eb5b 100644 --- a/gfx/webrender/res/debug_color.vs.glsl +++ b/gfx/webrender/res/debug_color.vs.glsl @@ -2,9 +2,12 @@ * 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/. */ +in vec4 aColor; +varying vec4 vColor; + void main(void) { - vColor = aColorRectTL; + vColor = aColor; vec4 pos = vec4(aPosition, 1.0); pos.xy = floor(pos.xy * uDevicePixelRatio + 0.5) / uDevicePixelRatio; gl_Position = uTransform * pos; diff --git a/gfx/webrender/res/debug_font.fs.glsl b/gfx/webrender/res/debug_font.fs.glsl index 5550fa934478..46acfb5b0e91 100644 --- a/gfx/webrender/res/debug_font.fs.glsl +++ b/gfx/webrender/res/debug_font.fs.glsl @@ -2,6 +2,9 @@ * 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/. */ +varying vec2 vColorTexCoord; +varying vec4 vColor; + void main(void) { #ifdef SERVO_ES2 diff --git a/gfx/webrender/res/debug_font.vs.glsl b/gfx/webrender/res/debug_font.vs.glsl index 9d9f38653cb3..e81a0c087e48 100644 --- a/gfx/webrender/res/debug_font.vs.glsl +++ b/gfx/webrender/res/debug_font.vs.glsl @@ -2,10 +2,16 @@ * 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/. */ +in vec4 aColor; +in vec4 aColorTexCoord; + +varying vec2 vColorTexCoord; +varying vec4 vColor; + void main(void) { - vColor = aColorRectTL; - vColorTexCoord = aColorTexCoordRectTop.xy; + vColor = aColor; + vColorTexCoord = aColorTexCoord.xy; vec4 pos = vec4(aPosition, 1.0); pos.xy = floor(pos.xy * uDevicePixelRatio + 0.5) / uDevicePixelRatio; gl_Position = uTransform * pos; diff --git a/gfx/webrender/res/prim_shared.glsl b/gfx/webrender/res/prim_shared.glsl index 5873f00c43cc..fed328df6ea7 100644 --- a/gfx/webrender/res/prim_shared.glsl +++ b/gfx/webrender/res/prim_shared.glsl @@ -3,6 +3,12 @@ * 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/. */ +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp sampler2DArray; +#else +precision mediump sampler2DArray; +#endif + #define PST_TOP_LEFT 0 #define PST_TOP 1 #define PST_TOP_RIGHT 2 @@ -59,12 +65,20 @@ uniform sampler2D sData64; uniform sampler2D sData128; uniform sampler2D sResourceRects; -ivec2 get_fetch_uv(int index, int vecs_per_item) { - int items_per_row = WR_MAX_VERTEX_TEXTURE_WIDTH / vecs_per_item; - int y = index / items_per_row; - int x = vecs_per_item * (index % items_per_row); - return ivec2(x, y); -} +// Instanced attributes +in int aGlobalPrimId; +in int aPrimitiveAddress; +in int aTaskIndex; +in int aClipTaskIndex; +in int aLayerIndex; +in int aElementIndex; +in ivec2 aUserData; + +// get_fetch_uv is a macro to work around a macOS Intel driver parsing bug. +// TODO: convert back to a function once the driver issues are resolved, if ever. +// https://github.com/servo/webrender/pull/623 +// https://github.com/servo/servo/issues/13953 +#define get_fetch_uv(i, vpi) ivec2(vpi * (i % (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi)), i / (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi)) ivec2 get_fetch_uv_1(int index) { return get_fetch_uv(index, 1); @@ -89,10 +103,6 @@ struct Layer { vec4 screen_vertices[4]; }; -layout(std140) uniform Data { - ivec4 int_data[WR_MAX_UBO_VECTORS]; -}; - Layer fetch_layer(int index) { Layer layer; @@ -279,66 +289,38 @@ struct PrimitiveInstance { ivec2 user_data; }; -PrimitiveInstance fetch_instance(int index) { +PrimitiveInstance fetch_prim_instance() { PrimitiveInstance pi; - int offset = index * 2; - - ivec4 data0 = int_data[offset + 0]; - ivec4 data1 = int_data[offset + 1]; - - pi.global_prim_index = data0.x; - pi.specific_prim_index = data0.y; - pi.render_task_index = data0.z; - pi.clip_task_index = data0.w; - pi.layer_index = data1.x; - pi.sub_index = data1.y; - pi.user_data = data1.zw; + pi.global_prim_index = aGlobalPrimId; + pi.specific_prim_index = aPrimitiveAddress; + pi.render_task_index = aTaskIndex; + pi.clip_task_index = aClipTaskIndex; + pi.layer_index = aLayerIndex; + pi.sub_index = aElementIndex; + pi.user_data = aUserData; return pi; } -struct BlurCommand { - int task_id; - int src_task_id; - int dir; -}; - -BlurCommand fetch_blur(int index) { - BlurCommand blur; - - int offset = index * 1; - - ivec4 data0 = int_data[offset + 0]; - - blur.task_id = data0.x; - blur.src_task_id = data0.y; - blur.dir = data0.z; - - return blur; -} - struct CachePrimitiveInstance { int global_prim_index; int specific_prim_index; int render_task_index; int sub_index; - ivec4 user_data; + ivec2 user_data; }; -CachePrimitiveInstance fetch_cache_instance(int index) { +CachePrimitiveInstance fetch_cache_instance() { CachePrimitiveInstance cpi; - int offset = index * 2; + PrimitiveInstance pi = fetch_prim_instance(); - ivec4 data0 = int_data[offset + 0]; - ivec4 data1 = int_data[offset + 1]; - - cpi.global_prim_index = data0.x; - cpi.specific_prim_index = data0.y; - cpi.render_task_index = data0.z; - cpi.sub_index = data0.w; - cpi.user_data = data1; + cpi.global_prim_index = pi.global_prim_index; + cpi.specific_prim_index = pi.specific_prim_index; + cpi.render_task_index = pi.render_task_index; + cpi.sub_index = pi.sub_index; + cpi.user_data = pi.user_data; return cpi; } @@ -356,11 +338,9 @@ struct Primitive { ivec2 user_data; }; -Primitive load_primitive(int index) { +Primitive load_primitive_custom(PrimitiveInstance pi) { Primitive prim; - PrimitiveInstance pi = fetch_instance(index); - prim.layer = fetch_layer(pi.layer_index); prim.tile = fetch_tile(pi.render_task_index); prim.clip_area = fetch_clip_area(pi.clip_task_index); @@ -376,6 +356,13 @@ Primitive load_primitive(int index) { return prim; } +Primitive load_primitive() { + PrimitiveInstance pi = fetch_prim_instance(); + + return load_primitive_custom(pi); +} + + // Return the intersection of the plane (set up by "normal" and "point") // with the ray (set up by "ray_origin" and "ray_dir"), // writing the resulting scaler into "t". @@ -643,7 +630,7 @@ BoxShadow fetch_boxshadow(int index) { } void write_clip(vec2 global_pos, ClipArea area) { - vec2 texture_size = textureSize(sCache, 0).xy; + vec2 texture_size = vec2(textureSize(sCache, 0).xy); vec2 uv = global_pos + area.task_bounds.xy - area.screen_origin_target_index.xy; vClipMaskUvBounds = area.task_bounds / texture_size.xyxy; vClipMaskUv = vec3(uv / texture_size, area.screen_origin_target_index.z); @@ -676,6 +663,6 @@ float do_clip() { vec4(vClipMaskUv.xy, vClipMaskUvBounds.zw)); // check for the dummy bounds, which are given to the opaque objects return vClipMaskUvBounds.xy == vClipMaskUvBounds.zw ? 1.0: - all(inside) ? textureLod(sCache, vClipMaskUv, 0).a : 0.0; + all(inside) ? textureLod(sCache, vClipMaskUv, 0.0).a : 0.0; } #endif //WR_FRAGMENT_SHADER diff --git a/gfx/webrender/res/ps_angle_gradient.vs.glsl b/gfx/webrender/res/ps_angle_gradient.vs.glsl index e1c91b544f84..2d7957633597 100644 --- a/gfx/webrender/res/ps_angle_gradient.vs.glsl +++ b/gfx/webrender/res/ps_angle_gradient.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); Gradient gradient = fetch_gradient(prim.prim_index); VertexInfo vi = write_vertex(prim.local_rect, diff --git a/gfx/webrender/res/ps_blend.vs.glsl b/gfx/webrender/res/ps_blend.vs.glsl index f37e7ce4985c..dd8568fb89ad 100644 --- a/gfx/webrender/res/ps_blend.vs.glsl +++ b/gfx/webrender/res/ps_blend.vs.glsl @@ -7,8 +7,8 @@ struct Blend { ivec4 src_id_target_id_op_amount; }; -Blend fetch_blend(int index) { - PrimitiveInstance pi = fetch_instance(index); +Blend fetch_blend() { + PrimitiveInstance pi = fetch_prim_instance(); Blend blend; blend.src_id_target_id_op_amount = ivec4(pi.user_data.x, @@ -20,7 +20,7 @@ Blend fetch_blend(int index) { } void main(void) { - Blend blend = fetch_blend(gl_InstanceID); + Blend blend = fetch_blend(); Tile src = fetch_tile(blend.src_id_target_id_op_amount.x); Tile dest = fetch_tile(blend.src_id_target_id_op_amount.y); diff --git a/gfx/webrender/res/ps_border.vs.glsl b/gfx/webrender/res/ps_border.vs.glsl index feafb6954671..dffabcdd3511 100644 --- a/gfx/webrender/res/ps_border.vs.glsl +++ b/gfx/webrender/res/ps_border.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); Border border = fetch_border(prim.prim_index); int sub_part = prim.sub_index; diff --git a/gfx/webrender/res/ps_box_shadow.vs.glsl b/gfx/webrender/res/ps_box_shadow.vs.glsl index 6b45af72d655..dcddc7f94b0c 100644 --- a/gfx/webrender/res/ps_box_shadow.vs.glsl +++ b/gfx/webrender/res/ps_box_shadow.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); BoxShadow bs = fetch_boxshadow(prim.prim_index); vec4 segment_rect = fetch_instance_geometry(prim.sub_index); diff --git a/gfx/webrender/res/ps_cache_image.vs.glsl b/gfx/webrender/res/ps_cache_image.vs.glsl index 57e380bbbed5..703df1c5192d 100644 --- a/gfx/webrender/res/ps_cache_image.vs.glsl +++ b/gfx/webrender/res/ps_cache_image.vs.glsl @@ -7,7 +7,7 @@ // target cache to the framebuffer, applying tile clip boundaries. void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); VertexInfo vi = write_vertex(prim.local_rect, prim.local_clip_rect, diff --git a/gfx/webrender/res/ps_clear.vs.glsl b/gfx/webrender/res/ps_clear.vs.glsl index 37c941b092b8..0b94afade228 100644 --- a/gfx/webrender/res/ps_clear.vs.glsl +++ b/gfx/webrender/res/ps_clear.vs.glsl @@ -4,12 +4,10 @@ * 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/. */ -layout(std140) uniform Data { - uvec4 data[WR_MAX_UBO_VECTORS]; -}; +in ivec4 aClearRectangle; void main() { - vec4 rect = vec4(data[gl_InstanceID]); + vec4 rect = vec4(aClearRectangle); vec4 pos = vec4(mix(rect.xy, rect.xy + rect.zw, aPosition.xy), 0, 1); gl_Position = uTransform * pos; diff --git a/gfx/webrender/res/ps_composite.vs.glsl b/gfx/webrender/res/ps_composite.vs.glsl index 42863f71efc7..b44cd30f2f00 100644 --- a/gfx/webrender/res/ps_composite.vs.glsl +++ b/gfx/webrender/res/ps_composite.vs.glsl @@ -7,8 +7,8 @@ struct Composite { ivec4 src0_src1_target_id_op; }; -Composite fetch_composite(int index) { - PrimitiveInstance pi = fetch_instance(index); +Composite fetch_composite() { + PrimitiveInstance pi = fetch_prim_instance(); Composite composite; composite.src0_src1_target_id_op = ivec4(pi.user_data.xy, @@ -19,7 +19,7 @@ Composite fetch_composite(int index) { } void main(void) { - Composite composite = fetch_composite(gl_InstanceID); + Composite composite = fetch_composite(); Tile src0 = fetch_tile(composite.src0_src1_target_id_op.x); Tile src1 = fetch_tile(composite.src0_src1_target_id_op.y); Tile dest = fetch_tile(composite.src0_src1_target_id_op.z); diff --git a/gfx/webrender/res/ps_gradient.vs.glsl b/gfx/webrender/res/ps_gradient.vs.glsl index 37d914a21d6a..226d8ec667fb 100644 --- a/gfx/webrender/res/ps_gradient.vs.glsl +++ b/gfx/webrender/res/ps_gradient.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); Gradient gradient = fetch_gradient(prim.prim_index); GradientStop g0 = fetch_gradient_stop(prim.sub_index + 0); diff --git a/gfx/webrender/res/ps_image.vs.glsl b/gfx/webrender/res/ps_image.vs.glsl index ae22ddd7e817..9125ba76f780 100644 --- a/gfx/webrender/res/ps_image.vs.glsl +++ b/gfx/webrender/res/ps_image.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); Image image = fetch_image(prim.prim_index); ResourceRect res = fetch_resource_rect(prim.user_data.x); diff --git a/gfx/webrender/res/ps_rectangle.vs.glsl b/gfx/webrender/res/ps_rectangle.vs.glsl index eace1763a667..6839b96dba18 100644 --- a/gfx/webrender/res/ps_rectangle.vs.glsl +++ b/gfx/webrender/res/ps_rectangle.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); Rectangle rect = fetch_rectangle(prim.prim_index); vColor = rect.color; #ifdef WR_FEATURE_TRANSFORM diff --git a/gfx/webrender/res/ps_text_run.vs.glsl b/gfx/webrender/res/ps_text_run.vs.glsl index 0fb5dd8f2669..dc82eed767c3 100644 --- a/gfx/webrender/res/ps_text_run.vs.glsl +++ b/gfx/webrender/res/ps_text_run.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); TextRun text = fetch_text_run(prim.prim_index); Glyph glyph = fetch_glyph(prim.sub_index); ResourceRect res = fetch_resource_rect(prim.user_data.x); diff --git a/gfx/webrender/res/ps_yuv_image.vs.glsl b/gfx/webrender/res/ps_yuv_image.vs.glsl index 091e5078414a..cf64dc4d1525 100644 --- a/gfx/webrender/res/ps_yuv_image.vs.glsl +++ b/gfx/webrender/res/ps_yuv_image.vs.glsl @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ void main(void) { - Primitive prim = load_primitive(gl_InstanceID); + Primitive prim = load_primitive(); #ifdef WR_FEATURE_TRANSFORM TransformVertexInfo vi = write_transform_vertex(prim.local_rect, prim.local_clip_rect, diff --git a/gfx/webrender/res/shared_other.glsl b/gfx/webrender/res/shared_other.glsl index c6f8286b6f81..03cad173cdb8 100644 --- a/gfx/webrender/res/shared_other.glsl +++ b/gfx/webrender/res/shared_other.glsl @@ -6,44 +6,18 @@ // Vertex shader attributes and uniforms //====================================================================================== #ifdef WR_VERTEX_SHADER - in vec4 aColorTexCoordRectTop; - in vec4 aColorRectTL; - - // box-shadow - in vec4 aBorderPosition; - in vec4 aBorderRadii; - in float aBlurRadius; - - // blur - in vec2 aDestTextureSize; - in vec2 aSourceTextureSize; #endif //====================================================================================== // Fragment shader attributes and uniforms //====================================================================================== #ifdef WR_FRAGMENT_SHADER - uniform vec2 uDirection; #endif //====================================================================================== // Interpolator definitions //====================================================================================== -// Hacks to be removed (needed for text etc) -varying vec2 vColorTexCoord; -varying vec4 vColor; - -// box_shadow -varying vec2 vPosition; -varying vec4 vBorderPosition; -varying vec4 vBorderRadii; -varying float vBlurRadius; - -// blur -varying vec2 vSourceTextureSize; -varying vec2 vDestTextureSize; - //====================================================================================== // VS only types and UBOs //====================================================================================== @@ -56,9 +30,4 @@ varying vec2 vDestTextureSize; // FS only functions //====================================================================================== #ifdef WR_FRAGMENT_SHADER - -void SetFragColor(vec4 color) { - oFragColor = color; -} - #endif diff --git a/gfx/webrender/src/debug_render.rs b/gfx/webrender/src/debug_render.rs index 8bd118e79fcd..02f1aa965a7b 100644 --- a/gfx/webrender/src/debug_render.rs +++ b/gfx/webrender/src/debug_render.rs @@ -31,9 +31,9 @@ impl DebugRenderer { let font_program_id = device.create_program("debug_font", "shared_other"); let color_program_id = device.create_program("debug_color", "shared_other"); - let font_vao = device.create_vao(VertexFormat::DebugFont, None); - let line_vao = device.create_vao(VertexFormat::DebugColor, None); - let tri_vao = device.create_vao(VertexFormat::DebugColor, None); + let font_vao = device.create_vao(VertexFormat::DebugFont, 32); + let line_vao = device.create_vao(VertexFormat::DebugColor, 32); + let tri_vao = device.create_vao(VertexFormat::DebugColor, 32); let font_texture_id = device.create_texture_ids(1, TextureTarget::Default)[0]; device.init_texture(font_texture_id, @@ -161,7 +161,7 @@ impl DebugRenderer { pub fn render(&mut self, device: &mut Device, viewport_size: &DeviceUintSize) { - let _ = GpuMarker::new("debug"); + let _gm = GpuMarker::new("debug"); device.disable_depth(); device.set_blend(true); device.set_blend_mode_alpha(); diff --git a/gfx/webrender/src/device.rs b/gfx/webrender/src/device.rs index b3f378e76da6..4993966f5d77 100644 --- a/gfx/webrender/src/device.rs +++ b/gfx/webrender/src/device.rs @@ -5,17 +5,17 @@ use euclid::Matrix4D; use fnv::FnvHasher; use gleam::gl; -use internal_types::{PackedVertex, PackedVertexForQuad}; -use internal_types::{RenderTargetMode, TextureSampler}; -use internal_types::{VertexAttribute, DebugFontVertex, DebugColorVertex, DEFAULT_TEXTURE}; +use internal_types::{PackedVertex, RenderTargetMode, TextureSampler, DEFAULT_TEXTURE}; +use internal_types::{BlurAttribute, ClearAttribute, ClipAttribute, VertexAttribute}; +use internal_types::{DebugFontVertex, DebugColorVertex}; //use notify::{self, Watcher}; use super::shader_source; use std::collections::HashMap; use std::fs::File; use std::hash::BuildHasherDefault; use std::io::Read; -use std::path::PathBuf; use std::mem; +use std::path::PathBuf; //use std::sync::mpsc::{channel, Sender}; //use std::thread; use webrender_traits::{ColorF, ImageFormat}; @@ -66,6 +66,9 @@ pub enum VertexFormat { Rectangles, DebugFont, DebugColor, + Clear, + Blur, + Clip, } fn get_optional_shader_source(shader_name: &str, base_path: &Option) -> Option { @@ -91,17 +94,18 @@ pub trait FileWatcherHandler : Send { } impl VertexFormat { - fn bind(&self, main: VBOId, aux: Option, offset: gl::GLuint) { + fn bind(&self, main: VBOId, instance: VBOId, offset: gl::GLuint, instance_stride: gl::GLint) { main.bind(); match *self { VertexFormat::DebugFont => { gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectTL as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorTexCoordRectTop as - gl::GLuint); + gl::enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint); + gl::enable_vertex_attrib_array(VertexAttribute::ColorTexCoord as gl::GLuint); - self.set_divisors(0); + gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); + gl::vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0); + gl::vertex_attrib_divisor(VertexAttribute::ColorTexCoord as gl::GLuint, 0); let vertex_stride = mem::size_of::() as gl::GLuint; @@ -111,13 +115,13 @@ impl VertexFormat { false, vertex_stride as gl::GLint, 0 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectTL as gl::GLuint, + gl::vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint, 4, gl::UNSIGNED_BYTE, true, vertex_stride as gl::GLint, 8 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorTexCoordRectTop as gl::GLuint, + gl::vertex_attrib_pointer(VertexAttribute::ColorTexCoord as gl::GLuint, 2, gl::FLOAT, false, @@ -126,9 +130,10 @@ impl VertexFormat { } VertexFormat::DebugColor => { gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectTL as gl::GLuint); + gl::enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint); - self.set_divisors(0); + gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); + gl::vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0); let vertex_stride = mem::size_of::() as gl::GLuint; @@ -138,17 +143,18 @@ impl VertexFormat { false, vertex_stride as gl::GLint, 0 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectTL as gl::GLuint, + gl::vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint, 4, gl::UNSIGNED_BYTE, true, vertex_stride as gl::GLint, 8 + vertex_stride * offset); } - VertexFormat::Rectangles => { - gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - + VertexFormat::Rectangles | + VertexFormat::Triangles => { let vertex_stride = mem::size_of::() as gl::GLuint; + gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); + gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); gl::vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint, 2, @@ -157,116 +163,113 @@ impl VertexFormat { vertex_stride as gl::GLint, 0); - aux.as_ref().unwrap().bind(); + instance.bind(); + let mut offset = 0; - gl::enable_vertex_attrib_array(VertexAttribute::PositionRect as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectTL as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectTR as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectBR as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorRectBL as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorTexCoordRectTop as - gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::ColorTexCoordRectBottom as - gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::MaskTexCoordRectTop as gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::MaskTexCoordRectBottom as - gl::GLuint); - gl::enable_vertex_attrib_array(VertexAttribute::Misc as gl::GLuint); + for &attrib in [VertexAttribute::GlobalPrimId, + VertexAttribute::PrimitiveAddress, + VertexAttribute::TaskIndex, + VertexAttribute::ClipTaskIndex, + VertexAttribute::LayerIndex, + VertexAttribute::ElementIndex, + ].into_iter() { + gl::enable_vertex_attrib_array(attrib as gl::GLuint); + gl::vertex_attrib_divisor(attrib as gl::GLuint, 1); + gl::vertex_attrib_i_pointer(attrib as gl::GLuint, + 1, + gl::INT, + instance_stride, + offset); + offset += 4; + } - self.set_divisors(1); - - let vertex_stride = mem::size_of::() as gl::GLuint; - - gl::vertex_attrib_pointer(VertexAttribute::PositionRect as gl::GLuint, - 4, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectTL as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - false, - vertex_stride as gl::GLint, - 16 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectTR as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - false, - vertex_stride as gl::GLint, - 20 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectBR as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - false, - vertex_stride as gl::GLint, - 24 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorRectBL as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - false, - vertex_stride as gl::GLint, - 28 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorTexCoordRectTop as gl::GLuint, - 4, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 32 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::ColorTexCoordRectBottom as gl::GLuint, - 4, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 48 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::MaskTexCoordRectTop as gl::GLuint, - 4, - gl::UNSIGNED_SHORT, - false, - vertex_stride as gl::GLint, - 64 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::MaskTexCoordRectBottom as gl::GLuint, - 4, - gl::UNSIGNED_SHORT, - false, - vertex_stride as gl::GLint, - 72 + vertex_stride * offset); - gl::vertex_attrib_pointer(VertexAttribute::Misc as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - false, - vertex_stride as gl::GLint, - 80 + vertex_stride * offset); + gl::enable_vertex_attrib_array(VertexAttribute::UserData as gl::GLuint); + gl::vertex_attrib_divisor(VertexAttribute::UserData as gl::GLuint, 1); + gl::vertex_attrib_i_pointer(VertexAttribute::UserData as gl::GLuint, + 2, + gl::INT, + instance_stride, + offset); } - VertexFormat::Triangles => { - gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - - self.set_divisors(0); - + VertexFormat::Clear => { let vertex_stride = mem::size_of::() as gl::GLuint; + gl::enable_vertex_attrib_array(ClearAttribute::Position as gl::GLuint); + gl::vertex_attrib_divisor(ClearAttribute::Position as gl::GLuint, 0); - gl::vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint, + gl::vertex_attrib_pointer(ClearAttribute::Position as gl::GLuint, 2, gl::FLOAT, false, vertex_stride as gl::GLint, - 0 + vertex_stride * offset); + 0); + + instance.bind(); + + gl::enable_vertex_attrib_array(ClearAttribute::Rectangle as gl::GLuint); + gl::vertex_attrib_divisor(ClearAttribute::Rectangle as gl::GLuint, 1); + gl::vertex_attrib_i_pointer(ClearAttribute::Rectangle as gl::GLuint, + 4, + gl::INT, + instance_stride, + 0); + } + VertexFormat::Blur => { + let vertex_stride = mem::size_of::() as gl::GLuint; + gl::enable_vertex_attrib_array(BlurAttribute::Position as gl::GLuint); + gl::vertex_attrib_divisor(BlurAttribute::Position as gl::GLuint, 0); + + gl::vertex_attrib_pointer(BlurAttribute::Position as gl::GLuint, + 2, + gl::FLOAT, + false, + vertex_stride as gl::GLint, + 0); + + instance.bind(); + + for (i, &attrib) in [BlurAttribute::RenderTaskIndex, + BlurAttribute::SourceTaskIndex, + BlurAttribute::Direction, + ].into_iter().enumerate() { + gl::enable_vertex_attrib_array(attrib as gl::GLuint); + gl::vertex_attrib_divisor(attrib as gl::GLuint, 1); + gl::vertex_attrib_i_pointer(attrib as gl::GLuint, + 1, + gl::INT, + instance_stride, + (i * 4) as gl::GLuint); + } + } + VertexFormat::Clip => { + let vertex_stride = mem::size_of::() as gl::GLuint; + gl::enable_vertex_attrib_array(ClipAttribute::Position as gl::GLuint); + gl::vertex_attrib_divisor(ClipAttribute::Position as gl::GLuint, 0); + + gl::vertex_attrib_pointer(ClipAttribute::Position as gl::GLuint, + 2, + gl::FLOAT, + false, + vertex_stride as gl::GLint, + 0); + + instance.bind(); + + for (i, &attrib) in [ClipAttribute::RenderTaskIndex, + ClipAttribute::LayerIndex, + ClipAttribute::DataIndex, + ClipAttribute::BaseTaskIndex, + ].into_iter().enumerate() { + gl::enable_vertex_attrib_array(attrib as gl::GLuint); + gl::vertex_attrib_divisor(attrib as gl::GLuint, 1); + gl::vertex_attrib_i_pointer(attrib as gl::GLuint, + 1, + gl::INT, + instance_stride, + (i * 4) as gl::GLuint); + } } } } - - fn set_divisors(&self, divisor: u32) { - gl::vertex_attrib_divisor(VertexAttribute::PositionRect as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorRectTL as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorRectTR as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorRectBR as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorRectBL as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorTexCoordRectTop as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::ColorTexCoordRectBottom as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::MaskTexCoordRectTop as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::MaskTexCoordRectBottom as gl::GLuint, divisor); - gl::vertex_attrib_divisor(VertexAttribute::Misc as gl::GLuint, divisor); - } } impl TextureId { @@ -362,49 +365,27 @@ impl Program { gl::attach_shader(self.id, fs_id); gl::bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition"); - gl::bind_attrib_location(self.id, - VertexAttribute::PositionRect as gl::GLuint, - "aPositionRect"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorRectTL as gl::GLuint, - "aColorRectTL"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorRectTR as gl::GLuint, - "aColorRectTR"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorRectBR as gl::GLuint, - "aColorRectBR"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorRectBL as gl::GLuint, - "aColorRectBL"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorTexCoordRectTop as gl::GLuint, - "aColorTexCoordRectTop"); - gl::bind_attrib_location(self.id, - VertexAttribute::MaskTexCoordRectTop as gl::GLuint, - "aMaskTexCoordRectTop"); - gl::bind_attrib_location(self.id, - VertexAttribute::ColorTexCoordRectBottom as gl::GLuint, - "aColorTexCoordRectBottom"); - gl::bind_attrib_location(self.id, - VertexAttribute::MaskTexCoordRectBottom as gl::GLuint, - "aMaskTexCoordRectBottom"); - gl::bind_attrib_location(self.id, - VertexAttribute::BorderRadii as gl::GLuint, - "aBorderRadii"); - gl::bind_attrib_location(self.id, - VertexAttribute::BorderPosition as gl::GLuint, - "aBorderPosition"); - gl::bind_attrib_location(self.id, - VertexAttribute::BlurRadius as gl::GLuint, - "aBlurRadius"); - gl::bind_attrib_location(self.id, - VertexAttribute::DestTextureSize as gl::GLuint, - "aDestTextureSize"); - gl::bind_attrib_location(self.id, - VertexAttribute::SourceTextureSize as gl::GLuint, - "aSourceTextureSize"); - gl::bind_attrib_location(self.id, VertexAttribute::Misc as gl::GLuint, "aMisc"); + gl::bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor"); + gl::bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord"); + + gl::bind_attrib_location(self.id, VertexAttribute::GlobalPrimId as gl::GLuint, "aGlobalPrimId"); + gl::bind_attrib_location(self.id, VertexAttribute::PrimitiveAddress as gl::GLuint, "aPrimitiveAddress"); + gl::bind_attrib_location(self.id, VertexAttribute::TaskIndex as gl::GLuint, "aTaskIndex"); + gl::bind_attrib_location(self.id, VertexAttribute::ClipTaskIndex as gl::GLuint, "aClipTaskIndex"); + gl::bind_attrib_location(self.id, VertexAttribute::LayerIndex as gl::GLuint, "aLayerIndex"); + gl::bind_attrib_location(self.id, VertexAttribute::ElementIndex as gl::GLuint, "aElementIndex"); + gl::bind_attrib_location(self.id, VertexAttribute::UserData as gl::GLuint, "aUserData"); + + gl::bind_attrib_location(self.id, ClearAttribute::Rectangle as gl::GLuint, "aClearRectangle"); + + gl::bind_attrib_location(self.id, BlurAttribute::RenderTaskIndex as gl::GLuint, "aBlurRenderTaskIndex"); + gl::bind_attrib_location(self.id, BlurAttribute::SourceTaskIndex as gl::GLuint, "aBlurSourceTaskIndex"); + gl::bind_attrib_location(self.id, BlurAttribute::Direction as gl::GLuint, "aBlurDirection"); + + gl::bind_attrib_location(self.id, ClipAttribute::RenderTaskIndex as gl::GLuint, "aClipRenderTaskIndex"); + gl::bind_attrib_location(self.id, ClipAttribute::LayerIndex as gl::GLuint, "aClipLayerIndex"); + gl::bind_attrib_location(self.id, ClipAttribute::DataIndex as gl::GLuint, "aClipDataIndex"); + gl::bind_attrib_location(self.id, ClipAttribute::BaseTaskIndex as gl::GLuint, "aClipBaseTaskIndex"); gl::link_program(self.id); if gl::get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) { @@ -430,30 +411,28 @@ impl Drop for Program { struct VAO { id: gl::GLuint, - vertex_format: VertexFormat, - main_vbo_id: VBOId, - aux_vbo_id: Option, ibo_id: IBOId, - owns_vbos: bool, + main_vbo_id: VBOId, + instance_vbo_id: VBOId, + instance_stride: gl::GLint, + owns_indices: bool, + owns_vertices: bool, + owns_instances: bool, } impl Drop for VAO { fn drop(&mut self) { gl::delete_vertex_arrays(&[self.id]); - if self.owns_vbos { - // In the case of a rect batch, the main VBO is the shared quad VBO, so keep that - // around. - if self.vertex_format != VertexFormat::Rectangles { - gl::delete_buffers(&[self.main_vbo_id.0]); - } - if let Some(VBOId(aux_vbo_id)) = self.aux_vbo_id { - gl::delete_buffers(&[aux_vbo_id]); - } - + if self.owns_indices { // todo(gw): maybe make these their own type with hashmap? - let IBOId(ibo_id) = self.ibo_id; - gl::delete_buffers(&[ibo_id]); + gl::delete_buffers(&[self.ibo_id.0]); + } + if self.owns_vertices { + gl::delete_buffers(&[self.main_vbo_id.0]); + } + if self.owns_instances { + gl::delete_buffers(&[self.instance_vbo_id.0]) } } } @@ -545,12 +524,12 @@ impl GpuFrameProfile { #[cfg(not(target_os = "android"))] fn add_marker(&mut self, tag: T) -> GpuMarker where T: NamedTag { - let marker = GpuMarker::new(tag.get_label()); - if self.pending_query != 0 { gl::end_query(gl::TIME_ELAPSED); } + let marker = GpuMarker::new(tag.get_label()); + if self.next_query < MAX_EVENTS_PER_FRAME { self.pending_query = self.queries[self.next_query]; gl::begin_query(gl::TIME_ELAPSED, self.pending_query); @@ -690,6 +669,7 @@ impl Drop for GpuMarker { pub enum VertexUsageHint { Static, Dynamic, + Stream, } impl VertexUsageHint { @@ -697,6 +677,7 @@ impl VertexUsageHint { match *self { VertexUsageHint::Static => gl::STATIC_DRAW, VertexUsageHint::Dynamic => gl::DYNAMIC_DRAW, + VertexUsageHint::Stream => gl::STREAM_DRAW, } } } @@ -1272,7 +1253,7 @@ impl Device { if let Some(shared_src) = get_optional_shader_source(base_filename, &self.resource_override_path) { include.push_str(&shared_src); - } + } let program = Program { name: base_filename.to_owned(), @@ -1592,10 +1573,13 @@ impl Device { fn create_vao_with_vbos(&mut self, format: VertexFormat, main_vbo_id: VBOId, - aux_vbo_id: Option, + instance_vbo_id: VBOId, ibo_id: IBOId, - offset: gl::GLuint, - owns_vbos: bool) + vertex_offset: gl::GLuint, + instance_stride: gl::GLint, + owns_vertices: bool, + owns_instances: bool, + owns_indices: bool) -> VAOId { debug_assert!(self.inside_frame); @@ -1604,15 +1588,18 @@ impl Device { gl::bind_vertex_array(vao_id); - format.bind(main_vbo_id, aux_vbo_id, offset); + format.bind(main_vbo_id, instance_vbo_id, vertex_offset, instance_stride); + ibo_id.bind(); // force it to be a part of VAO let vao = VAO { id: vao_id, - vertex_format: format, - main_vbo_id: main_vbo_id, - aux_vbo_id: aux_vbo_id, ibo_id: ibo_id, - owns_vbos: owns_vbos, + main_vbo_id: main_vbo_id, + instance_vbo_id: instance_vbo_id, + instance_stride: instance_stride, + owns_indices: owns_indices, + owns_vertices: owns_vertices, + owns_instances: owns_instances, }; gl::bind_vertex_array(0); @@ -1625,21 +1612,29 @@ impl Device { vao_id } - pub fn create_vao(&mut self, format: VertexFormat, quad_vertex_buffer: Option) - -> VAOId { + pub fn create_vao(&mut self, format: VertexFormat, inst_stride: gl::GLint) -> VAOId { debug_assert!(self.inside_frame); - let buffer_ids = gl::gen_buffers(2); + let buffer_ids = gl::gen_buffers(3); let ibo_id = IBOId(buffer_ids[0]); - let (main_vbo_id, aux_vbo_id) = if format == VertexFormat::Rectangles { - (quad_vertex_buffer.expect("A quad vertex buffer must be supplied to `create_vao()` if - we are to render rectangles!"), - Some(VBOId(buffer_ids[1]))) - } else { - (VBOId(buffer_ids[1]), None) + let main_vbo_id = VBOId(buffer_ids[1]); + let intance_vbo_id = VBOId(buffer_ids[2]); + + self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, true, true, true) + } + + pub fn create_vao_with_new_instances(&mut self, format: VertexFormat, inst_stride: gl::GLint, + base_vao: VAOId) -> VAOId { + debug_assert!(self.inside_frame); + + let buffer_ids = gl::gen_buffers(1); + let intance_vbo_id = VBOId(buffer_ids[0]); + let (main_vbo_id, ibo_id) = { + let vao = self.vaos.get(&base_vao).unwrap(); + (vao.main_vbo_id, vao.ibo_id) }; - self.create_vao_with_vbos(format, main_vbo_id, aux_vbo_id, ibo_id, 0, true) + self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, false, true, false) } pub fn update_vao_main_vertices(&mut self, @@ -1649,12 +1644,26 @@ impl Device { debug_assert!(self.inside_frame); let vao = self.vaos.get(&vao_id).unwrap(); - debug_assert!(self.bound_vao == vao_id); + debug_assert_eq!(self.bound_vao, vao_id); vao.main_vbo_id.bind(); gl::buffer_data(gl::ARRAY_BUFFER, &vertices, usage_hint.to_gl()); } + pub fn update_vao_instances(&mut self, + vao_id: VAOId, + instances: &[V], + usage_hint: VertexUsageHint) { + debug_assert!(self.inside_frame); + + let vao = self.vaos.get(&vao_id).unwrap(); + debug_assert_eq!(self.bound_vao, vao_id); + debug_assert_eq!(vao.instance_stride as usize, mem::size_of::()); + + vao.instance_vbo_id.bind(); + gl::buffer_data(gl::ARRAY_BUFFER, &instances, usage_hint.to_gl()); + } + pub fn update_vao_indices(&mut self, vao_id: VAOId, indices: &[I], @@ -1662,7 +1671,7 @@ impl Device { debug_assert!(self.inside_frame); let vao = self.vaos.get(&vao_id).unwrap(); - debug_assert!(self.bound_vao == vao_id); + debug_assert_eq!(self.bound_vao, vao_id); vao.ibo_id.bind(); gl::buffer_data(gl::ELEMENT_ARRAY_BUFFER, &indices, usage_hint.to_gl()); diff --git a/gfx/webrender/src/frame.rs b/gfx/webrender/src/frame.rs index d37b6feaad31..f557a64bf136 100644 --- a/gfx/webrender/src/frame.rs +++ b/gfx/webrender/src/frame.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; -use euclid::{Point2D, Point3D, Rect, Size2D}; +use euclid::Point3D; use fnv::FnvHasher; use geometry::ray_intersects_rect; use internal_types::{ANGLE_FLOAT_TO_FIXED, AxisDirection}; @@ -16,14 +16,13 @@ use scene::Scene; use std::collections::{HashMap, HashSet}; use std::hash::BuildHasherDefault; use tiling::{AuxiliaryListsMap, FrameBuilder, FrameBuilderConfig, LayerMap, PrimitiveFlags}; -use util::MatrixHelpers; use webrender_traits::{AuxiliaryLists, PipelineId, Epoch, ScrollPolicy, ScrollLayerId}; use webrender_traits::{ClipRegion, ColorF, DisplayItem, StackingContext, FilterOp, MixBlendMode}; use webrender_traits::{ScrollEventPhase, ScrollLayerInfo, ScrollLocation, SpecificDisplayItem, ScrollLayerState}; use webrender_traits::{LayerRect, LayerPoint, LayerSize}; use webrender_traits::{ServoScrollRootId, ScrollLayerRect, as_scroll_parent_rect, ScrollLayerPixel}; -use webrender_traits::WorldPoint4D; -use webrender_traits::{LayerTransform, LayerToScrollTransform, ScrollToWorldTransform}; +use webrender_traits::{WorldPoint, WorldPoint4D}; +use webrender_traits::{LayerToScrollTransform, ScrollToWorldTransform}; #[cfg(target_os = "macos")] const CAN_OVERSCROLL: bool = true; @@ -38,7 +37,7 @@ static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF { r: 0.3, g: 0.3, b: 0.3, a: 0.6 struct FlattenContext<'a> { scene: &'a Scene, - pipeline_sizes: &'a mut HashMap>, + pipeline_sizes: &'a mut HashMap, builder: &'a mut FrameBuilder, } @@ -234,7 +233,7 @@ impl Frame { old_layer_scrolling_states } - pub fn get_scroll_layer(&self, cursor: &Point2D, scroll_layer_id: ScrollLayerId) + pub fn get_scroll_layer(&self, cursor: &WorldPoint, scroll_layer_id: ScrollLayerId) -> Option { self.layers.get(&scroll_layer_id).and_then(|layer| { for child_layer_id in layer.children.iter().rev() { @@ -286,7 +285,7 @@ impl Frame { result.push(ScrollLayerState { pipeline_id: scroll_layer.pipeline_id, scroll_root_id: servo_scroll_root_id, - scroll_offset: scroll_layer.scrolling.offset.to_untyped(), + scroll_offset: scroll_layer.scrolling.offset, }) } ScrollLayerInfo::Fixed => {} @@ -297,7 +296,7 @@ impl Frame { /// Returns true if any layers actually changed position or false otherwise. pub fn scroll_layers(&mut self, - origin: Point2D, + origin: LayerPoint, pipeline_id: PipelineId, scroll_root_id: ServoScrollRootId) -> bool { @@ -330,7 +329,7 @@ impl Frame { /// Returns true if any layers actually changed position or false otherwise. pub fn scroll(&mut self, scroll_location: ScrollLocation, - cursor: Point2D, + cursor: WorldPoint, phase: ScrollEventPhase) -> bool { let root_scroll_layer_id = match self.root_scroll_layer_id { @@ -384,7 +383,7 @@ impl Frame { // Nothing to do on this layer. continue; } - + layer.scrolling.offset.y = end_pos; scrolled_a_layer = true; continue; @@ -460,7 +459,7 @@ impl Frame { pub fn create(&mut self, scene: &Scene, - pipeline_sizes: &mut HashMap>) { + pipeline_sizes: &mut HashMap) { let root_pipeline_id = match scene.root_pipeline_id { Some(root_pipeline_id) => root_pipeline_id, None => return, @@ -496,9 +495,9 @@ impl Frame { // Insert global position: fixed elements layer debug_assert!(self.layers.is_empty()); let root_fixed_layer_id = ScrollLayerId::create_fixed(root_pipeline_id); - let root_viewport = LayerRect::new(LayerPoint::zero(), LayerSize::from_untyped(&root_pipeline.viewport_size)); + let root_viewport = LayerRect::new(LayerPoint::zero(), root_pipeline.viewport_size); let layer = Layer::new(&root_viewport, - LayerSize::from_untyped(&root_clip.main.size), + root_clip.main.size, &LayerToScrollTransform::identity(), root_pipeline_id); self.layers.insert(root_fixed_layer_id, layer.clone()); @@ -587,7 +586,7 @@ impl Frame { LayerSize::new(content_size.width + clip.origin.x, content_size.height + clip.origin.y)); context.builder.push_layer(layer_rect, - &ClipRegion::simple(&layer_rect.to_untyped()), + &ClipRegion::simple(&layer_rect), LayerToScrollTransform::identity(), pipeline_id, current_scroll_layer_id, @@ -638,14 +637,11 @@ impl Frame { } } - // TODO(nical): make them LayerTransforms in the public API. - let sc_transform: LayerTransform = unsafe { ::std::mem::transmute(stacking_context.transform) }; - let sc_perspective: LayerTransform = unsafe { ::std::mem::transmute(stacking_context.perspective) }; let transform = layer_relative_transform.pre_translated(stacking_context.bounds.origin.x, stacking_context.bounds.origin.y, 0.0) - .pre_mul(&sc_transform) - .pre_mul(&sc_perspective); + .pre_mul(&stacking_context.transform) + .pre_mul(&stacking_context.perspective); // Build world space transform let scroll_layer_id = match stacking_context.scroll_policy { @@ -654,45 +650,32 @@ impl Frame { }; if level == 0 { - // Add a large white rectangle as the root display item if there is no root stacking - // context background color. This is removed by the occlusion culling for most tiles, - // and means that it's no longer necessary to clear the framebuffer. - // - // TODO(nical) Should painting a white background be optional if there is no stacking - // context background color? On deferred GPUs we probably still want to clear the - // framebuffer and Gecko currently supports semi-transparent windows. - // - // If we do need this, does it make sense to keep Frame::clear_tiles? - let mut root_background_color = match context.scene.pipeline_map.get(&pipeline_id) { - Some(pipeline) => pipeline.background_color, - None => ColorF::new(1.0, 1.0, 1.0, 1.0), - }; + if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) { + if let Some(bg_color) = pipeline.background_color { - if root_background_color.a == 0.0 { - root_background_color = ColorF::new(1.0, 1.0, 1.0, 1.0); + // Adding a dummy layer for this rectangle in order to disable clipping. + let no_clip = ClipRegion::simple(&clip_region.main); + context.builder.push_layer(clip_region.main, + &no_clip, + transform, + pipeline_id, + scroll_layer_id, + &composition_operations); + + //Note: we don't use the original clip region here, + // it's already processed by the layer we just pushed. + context.builder.add_solid_rectangle(&clip_region.main, + &no_clip, + &bg_color, + PrimitiveFlags::None); + + context.builder.pop_layer(); + } } - - // Adding a dummy layer for this rectangle in order to disable clipping. - let no_clip = ClipRegion::simple(&clip_region.main); - context.builder.push_layer(LayerRect::from_untyped(&clip_region.main), - &no_clip, - transform, - pipeline_id, - scroll_layer_id, - &composition_operations); - - //Note: we don't use the original clip region here, - // it's already processed by the layer we just pushed. - context.builder.add_solid_rectangle(&LayerRect::from_untyped(&clip_region.main), - &no_clip, - &root_background_color, - PrimitiveFlags::None); - - context.builder.pop_layer(); } // TODO(gw): Int with overflow etc - context.builder.push_layer(LayerRect::from_untyped(&clip_region.main), + context.builder.push_layer(clip_region.main, &clip_region, transform, pipeline_id, @@ -710,7 +693,7 @@ impl Frame { 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(&scrollbar_rect, - &ClipRegion::simple(&scrollbar_rect.to_untyped()), + &ClipRegion::simple(&scrollbar_rect), &DEFAULT_SCROLLBAR_COLOR, PrimitiveFlags::Scrollbar(self.root_scroll_layer_id.unwrap(), 4.0)); @@ -721,7 +704,7 @@ impl Frame { fn flatten_iframe<'a>(&mut self, pipeline_id: PipelineId, - bounds: &Rect, + bounds: &LayerRect, context: &mut FlattenContext, current_scroll_layer_id: ScrollLayerId, layer_relative_transform: LayerToScrollTransform) { @@ -748,7 +731,7 @@ impl Frame { self.pipeline_epoch_map.insert(pipeline_id, pipeline.epoch); - let iframe_rect = &LayerRect::new(LayerPoint::zero(), LayerSize::from_untyped(&bounds.size)); + let iframe_rect = &LayerRect::new(LayerPoint::zero(), bounds.size); let transform = layer_relative_transform.pre_translated(bounds.origin.x, bounds.origin.y, 0.0); @@ -757,7 +740,7 @@ impl Frame { let iframe_scroll_layer_id = ScrollLayerId::root(pipeline_id); let layer = Layer::new(iframe_rect, - LayerSize::from_untyped(&iframe_clip.main.size), + iframe_clip.main.size, &transform, pipeline_id); self.layers.insert(iframe_fixed_layer_id, layer.clone()); @@ -788,19 +771,19 @@ impl Frame { while let Some(item) = traversal.next() { match item.item { SpecificDisplayItem::WebGL(ref info) => { - context.builder.add_webgl_rectangle(LayerRect::from_untyped(&item.rect), + context.builder.add_webgl_rectangle(item.rect, &item.clip, info.context_id); } SpecificDisplayItem::Image(ref info) => { - context.builder.add_image(LayerRect::from_untyped(&item.rect), + context.builder.add_image(item.rect, &item.clip, - &LayerSize::from_untyped(&info.stretch_size), - &LayerSize::from_untyped(&info.tile_spacing), + &info.stretch_size, + &info.tile_spacing, info.image_key, info.image_rendering); } SpecificDisplayItem::YuvImage(ref info) => { - context.builder.add_yuv_image(LayerRect::from_untyped(&item.rect), + context.builder.add_yuv_image(item.rect, &item.clip, info.y_image_key, info.u_image_key, @@ -808,7 +791,7 @@ impl Frame { info.color_space); } SpecificDisplayItem::Text(ref text_info) => { - context.builder.add_text(LayerRect::from_untyped(&item.rect), + context.builder.add_text(item.rect, &item.clip, text_info.font_key, text_info.size, @@ -817,22 +800,22 @@ impl Frame { text_info.glyphs); } SpecificDisplayItem::Rectangle(ref info) => { - context.builder.add_solid_rectangle(&LayerRect::from_untyped(&item.rect), + context.builder.add_solid_rectangle(&item.rect, &item.clip, &info.color, PrimitiveFlags::None); } SpecificDisplayItem::Gradient(ref info) => { - context.builder.add_gradient(LayerRect::from_untyped(&item.rect), + context.builder.add_gradient(item.rect, &item.clip, - LayerPoint::from_untyped(&info.start_point), - LayerPoint::from_untyped(&info.end_point), + info.start_point, + info.end_point, info.stops); } SpecificDisplayItem::BoxShadow(ref box_shadow_info) => { - context.builder.add_box_shadow(&LayerRect::from_untyped(&box_shadow_info.box_bounds), + context.builder.add_box_shadow(&box_shadow_info.box_bounds, &item.clip, - &LayerPoint::from_untyped(&box_shadow_info.offset), + &box_shadow_info.offset, &box_shadow_info.color, box_shadow_info.blur_radius, box_shadow_info.spread_radius, @@ -840,7 +823,7 @@ impl Frame { box_shadow_info.clip_mode); } SpecificDisplayItem::Border(ref info) => { - context.builder.add_border(LayerRect::from_untyped(&item.rect), &item.clip, info); + context.builder.add_border(item.rect, &item.clip, info); } SpecificDisplayItem::PushStackingContext(ref info) => { self.flatten_stacking_context(traversal, @@ -861,8 +844,8 @@ impl Frame { current_scroll_layer_id, layer_relative_transform, level, - &LayerRect::from_untyped(&item.rect), - &LayerSize::from_untyped(&info.content_size), + &item.rect, + &info.content_size, info.id); } SpecificDisplayItem::Iframe(ref info) => { diff --git a/gfx/webrender/src/internal_types.rs b/gfx/webrender/src/internal_types.rs index 8c02acfee85c..137d92f7c37e 100644 --- a/gfx/webrender/src/internal_types.rs +++ b/gfx/webrender/src/internal_types.rs @@ -4,7 +4,7 @@ use app_units::Au; use device::TextureFilter; -use euclid::{Size2D, TypedPoint2D, UnknownUnit}; +use euclid::{TypedPoint2D, UnknownUnit}; use fnv::FnvHasher; use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle}; use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher}; @@ -18,7 +18,7 @@ use std::{i32, usize}; use std::path::PathBuf; use std::sync::Arc; use tiling; -use webrender_traits::{Epoch, ColorF, PipelineId}; +use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize}; use webrender_traits::{ImageFormat, MixBlendMode, NativeFontHandle}; use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand}; @@ -63,12 +63,12 @@ impl GLContextHandleWrapper { } pub fn new_context(&self, - size: Size2D, + size: DeviceIntSize, attributes: GLContextAttributes, dispatcher: Option>) -> Result { match *self { GLContextHandleWrapper::Native(ref handle) => { - let ctx = GLContext::::new_shared_with_dispatcher(size, + let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), attributes, ColorAttachmentType::Texture, Some(handle), @@ -76,7 +76,7 @@ impl GLContextHandleWrapper { ctx.map(GLContextWrapper::Native) } GLContextHandleWrapper::OSMesa(ref handle) => { - let ctx = GLContext::::new_shared_with_dispatcher(size, + let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), attributes, ColorAttachmentType::Texture, Some(handle), @@ -126,7 +126,7 @@ impl GLContextWrapper { } } - pub fn get_info(&self) -> (Size2D, u32, GLLimits) { + pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) { match *self { GLContextWrapper::Native(ref ctx) => { let (real_size, texture_id) = { @@ -136,7 +136,7 @@ impl GLContextWrapper { let limits = ctx.borrow_limits().clone(); - (real_size, texture_id, limits) + (DeviceIntSize::from_untyped(&real_size), texture_id, limits) } GLContextWrapper::OSMesa(ref ctx) => { let (real_size, texture_id) = { @@ -146,18 +146,18 @@ impl GLContextWrapper { let limits = ctx.borrow_limits().clone(); - (real_size, texture_id, limits) + (DeviceIntSize::from_untyped(&real_size), texture_id, limits) } } } - pub fn resize(&mut self, size: &Size2D) -> Result<(), &'static str> { + pub fn resize(&mut self, size: &DeviceIntSize) -> Result<(), &'static str> { match *self { GLContextWrapper::Native(ref mut ctx) => { - ctx.resize(*size) + ctx.resize(size.to_untyped()) } GLContextWrapper::OSMesa(ref mut ctx) => { - ctx.resize(*size) + ctx.resize(size.to_untyped()) } } } @@ -223,23 +223,49 @@ impl BatchTextures { // In some places we need to temporarily bind a texture to any slot. pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0; +#[derive(Clone, Copy, Debug)] pub enum VertexAttribute { + // vertex-frequency basic attributes Position, - PositionRect, - ColorRectTL, - ColorRectTR, - ColorRectBR, - ColorRectBL, - ColorTexCoordRectTop, - MaskTexCoordRectTop, - ColorTexCoordRectBottom, - MaskTexCoordRectBottom, - BorderRadii, - BorderPosition, - BlurRadius, - DestTextureSize, - SourceTextureSize, - Misc, + Color, + ColorTexCoord, + // instance-frequency primitive attributes + GlobalPrimId, + PrimitiveAddress, + TaskIndex, + ClipTaskIndex, + LayerIndex, + ElementIndex, + UserData, +} + +#[derive(Clone, Copy, Debug)] +pub enum ClearAttribute { + // vertex frequency + Position, + // instance frequency + Rectangle, +} + +#[derive(Clone, Copy, Debug)] +pub enum BlurAttribute { + // vertex frequency + Position, + // instance frequency + RenderTaskIndex, + SourceTaskIndex, + Direction, +} + +#[derive(Clone, Copy, Debug)] +pub enum ClipAttribute { + // vertex frequency + Position, + // instance frequency + RenderTaskIndex, + LayerIndex, + DataIndex, + BaseTaskIndex, } #[derive(Debug, Clone, Copy)] @@ -262,39 +288,6 @@ impl PackedColor { } } -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct PackedVertexForQuad { - pub x: f32, - pub y: f32, - pub width: f32, - pub height: f32, - pub color_tl: PackedColor, - pub color_tr: PackedColor, - pub color_br: PackedColor, - pub color_bl: PackedColor, - pub u_tl: f32, - pub v_tl: f32, - pub u_tr: f32, - pub v_tr: f32, - pub u_br: f32, - pub v_br: f32, - pub u_bl: f32, - pub v_bl: f32, - pub mu_tl: u16, - pub mv_tl: u16, - pub mu_tr: u16, - pub mv_tr: u16, - pub mu_br: u16, - pub mv_br: u16, - pub mu_bl: u16, - pub mv_bl: u16, - pub matrix_index: u8, - pub clip_in_rect_index: u8, - pub clip_out_rect_index: u8, - pub tile_params_index: u8, -} - #[derive(Debug, Clone, Copy)] #[repr(C)] pub struct PackedVertex { diff --git a/gfx/webrender/src/mask_cache.rs b/gfx/webrender/src/mask_cache.rs index 2ab6a1425112..89bec631ed73 100644 --- a/gfx/webrender/src/mask_cache.rs +++ b/gfx/webrender/src/mask_cache.rs @@ -23,7 +23,7 @@ impl ClipSource { match self { &ClipSource::NoClip => None, &ClipSource::Complex(rect, _) => Some(rect), - &ClipSource::Region(ref region) => Some(LayerRect::from_untyped(®ion.main)), + &ClipSource::Region(ref region) => Some(region.main), } } } @@ -113,15 +113,14 @@ impl MaskCacheInfo { PrimitiveStore::populate_clip_data(slice, data); debug_assert_eq!(self.clip_range.item_count, 1); local_rect = Some(rect); - local_inner = ComplexClipRegion::new(rect.to_untyped(), - BorderRadius::uniform(radius)) - .get_inner_rect().map(|r|{ LayerRect::from_untyped(&r) }); + local_inner = ComplexClipRegion::new(rect, BorderRadius::uniform(radius)) + .get_inner_rect(); } &ClipSource::Region(ref region) => { local_rect = Some(LayerRect::from_untyped(&rect_from_points_f(-MAX_COORD, -MAX_COORD, MAX_COORD, MAX_COORD))); local_inner = match region.image_mask { Some(ref mask) if !mask.repeat => { - local_rect = local_rect.and_then(|r| r.intersection(&LayerRect::from_untyped(&mask.rect))); + local_rect = local_rect.and_then(|r| r.intersection(&mask.rect)); None }, Some(_) => None, @@ -133,9 +132,9 @@ impl MaskCacheInfo { for (clip, chunk) in clips.iter().zip(slice.chunks_mut(CLIP_DATA_GPU_SIZE)) { let data = ClipData::from_clip_region(clip); PrimitiveStore::populate_clip_data(chunk, data); - local_rect = local_rect.and_then(|r| r.intersection(&LayerRect::from_untyped(&clip.rect))); + local_rect = local_rect.and_then(|r| r.intersection(&clip.rect)); local_inner = local_inner.and_then(|r| clip.get_inner_rect() - .and_then(|ref inner| r.intersection(&LayerRect::from_untyped(&inner)))); + .and_then(|ref inner| r.intersection(&inner))); } } }; diff --git a/gfx/webrender/src/prim_store.rs b/gfx/webrender/src/prim_store.rs index 91141d7e924f..0cf25558a6a3 100644 --- a/gfx/webrender/src/prim_store.rs +++ b/gfx/webrender/src/prim_store.rs @@ -317,7 +317,7 @@ impl ClipData { pub fn from_clip_region(clip: &ComplexClipRegion) -> ClipData { ClipData { rect: ClipRect { - rect: LayerRect::from_untyped(&clip.rect), + rect: clip.rect, padding: [0.0, 0.0, 0.0, 0.0], }, top_left: ClipCorner { @@ -642,7 +642,7 @@ impl PrimitiveStore { uv_rect: DeviceRect::new(cache_item.uv0, DeviceSize::new(cache_item.uv1.x - cache_item.uv0.x, cache_item.uv1.y - cache_item.uv0.y)), - local_rect: LayerRect::from_untyped(&mask.rect), + local_rect: mask.rect, }); } } @@ -769,7 +769,7 @@ impl PrimitiveStore { let (rect, is_complex) = match source { ClipSource::NoClip => (None, false), ClipSource::Complex(rect, radius) => (Some(rect), radius > 0.0), - ClipSource::Region(ref region) => (Some(LayerRect::from_untyped(®ion.main)), region.is_complex()), + ClipSource::Region(ref region) => (Some(region.main), region.is_complex()), }; if let Some(rect) = rect { self.gpu_geometry.get_mut(GpuStoreAddress(index.0 as i32)) diff --git a/gfx/webrender/src/profiler.rs b/gfx/webrender/src/profiler.rs index 62fe09af337f..d1f6d375d1a0 100644 --- a/gfx/webrender/src/profiler.rs +++ b/gfx/webrender/src/profiler.rs @@ -618,7 +618,7 @@ impl Profiler { renderer_timers: &mut RendererProfileTimers, debug_renderer: &mut DebugRenderer) { - let _ = GpuMarker::new("profile"); + let _gm = GpuMarker::new("profile"); self.x_left = 20.0; self.y_left = 40.0; self.x_right = 400.0; diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs index 10aa4e115e0d..33c9275a4191 100644 --- a/gfx/webrender/src/render_backend.rs +++ b/gfx/webrender/src/render_backend.rs @@ -18,7 +18,6 @@ use std::sync::mpsc::Sender; use texture_cache::TextureCache; use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, ImageData}; use webrender_traits::{RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId}; -use webrender_traits::{DeviceIntSize}; use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver}; use webrender_traits::{VRCompositorCommand, VRCompositorHandler}; use tiling::FrameBuilderConfig; @@ -299,7 +298,7 @@ impl RenderBackend { self.resource_cache .add_webgl_texture(id, SourceTexture::WebGL(texture_id), - DeviceIntSize::from_untyped(&real_size)); + real_size); tx.send(Ok((id, limits))).unwrap(); }, @@ -320,7 +319,7 @@ impl RenderBackend { let (real_size, texture_id, _) = ctx.get_info(); self.resource_cache .update_webgl_texture(context_id, SourceTexture::WebGL(texture_id), - DeviceIntSize::from_untyped(&real_size)); + real_size); }, Err(msg) => { error!("Error resizing WebGLContext: {}", msg); diff --git a/gfx/webrender/src/renderer.rs b/gfx/webrender/src/renderer.rs index d1a43020022f..228453de10cf 100644 --- a/gfx/webrender/src/renderer.rs +++ b/gfx/webrender/src/renderer.rs @@ -13,7 +13,7 @@ use debug_colors; use debug_render::DebugRenderer; use device::{Device, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler}; use device::{TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget}; -use euclid::{Size2D, Matrix4D}; +use euclid::Matrix4D; use fnv::FnvHasher; use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp}; use internal_types::{TextureUpdateList, PackedVertex, RenderTargetMode}; @@ -32,8 +32,8 @@ use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread; use texture_cache::TextureCache; -use tiling::{self, Frame, FrameBuilderConfig, PrimitiveBatchData}; -use tiling::{RenderTarget, ClearTile}; +use tiling::{Frame, FrameBuilderConfig, PrimitiveBatchData}; +use tiling::{BlurCommand, CacheClipInstance, ClearTile, PrimitiveInstance, RenderTarget}; use time::precise_time_ns; use util::TransformedRectKind; use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher}; @@ -44,8 +44,6 @@ use webrender_traits::VRCompositorHandler; pub const MAX_VERTEX_TEXTURE_WIDTH: usize = 1024; -const UBO_BIND_DATA: u32 = 1; - const GPU_TAG_CACHE_BOX_SHADOW: GpuProfileTag = GpuProfileTag { label: "C_BoxShadow", color: debug_colors::BLACK }; const GPU_TAG_CACHE_CLIP: GpuProfileTag = GpuProfileTag { label: "C_Clip", color: debug_colors::PURPLE }; const GPU_TAG_CACHE_TEXT_RUN: GpuProfileTag = GpuProfileTag { label: "C_TextRun", color: debug_colors::MISTYROSE }; @@ -134,14 +132,12 @@ struct LazilyCompiledShader { id: Option, name: &'static str, kind: ShaderKind, - max_ubo_vectors: usize, features: Vec<&'static str>, } impl LazilyCompiledShader { fn new(kind: ShaderKind, name: &'static str, - max_ubo_vectors: usize, features: &[&'static str], device: &mut Device, precache: bool) -> LazilyCompiledShader { @@ -149,7 +145,6 @@ impl LazilyCompiledShader { id: None, name: name, kind: kind, - max_ubo_vectors: max_ubo_vectors, features: features.to_vec(), }; @@ -164,20 +159,15 @@ impl LazilyCompiledShader { if self.id.is_none() { let id = match self.kind { ShaderKind::Clear => { - create_clear_shader(self.name, - device, - self.max_ubo_vectors) + create_clear_shader(self.name, device) } ShaderKind::Primitive | ShaderKind::Cache => { create_prim_shader(self.name, device, - self.max_ubo_vectors, &self.features) } ShaderKind::ClipCache => { - create_clip_shader(self.name, - device, - self.max_ubo_vectors) + create_clip_shader(self.name, device) } }; self.id = Some(id); @@ -190,7 +180,6 @@ impl LazilyCompiledShader { struct PrimitiveShader { simple: LazilyCompiledShader, transform: LazilyCompiledShader, - max_items: usize, } struct FileWatcher { @@ -206,7 +195,7 @@ impl FileWatcherHandler for FileWatcher { } } -fn get_ubo_max_len(max_ubo_size: usize) -> usize { +fn _get_ubo_max_len(max_ubo_size: usize) -> usize { let item_size = mem::size_of::(); let max_items = max_ubo_size / item_size; @@ -219,14 +208,11 @@ fn get_ubo_max_len(max_ubo_size: usize) -> usize { impl PrimitiveShader { fn new(name: &'static str, - max_ubo_vectors: usize, - max_prim_items: usize, device: &mut Device, features: &[&'static str], precache: bool) -> PrimitiveShader { let simple = LazilyCompiledShader::new(ShaderKind::Primitive, name, - max_ubo_vectors, features, device, precache); @@ -236,7 +222,6 @@ impl PrimitiveShader { let transform = LazilyCompiledShader::new(ShaderKind::Primitive, name, - max_ubo_vectors, &transform_features, device, precache); @@ -244,29 +229,23 @@ impl PrimitiveShader { PrimitiveShader { simple: simple, transform: transform, - max_items: max_prim_items, } } fn get(&mut self, device: &mut Device, - transform_kind: TransformedRectKind) -> (ProgramId, usize) { - let shader = match transform_kind { + transform_kind: TransformedRectKind) -> ProgramId { + match transform_kind { TransformedRectKind::AxisAligned => self.simple.get(device), TransformedRectKind::Complex => self.transform.get(device), - }; - - (shader, self.max_items) + } } } fn create_prim_shader(name: &'static str, device: &mut Device, - max_ubo_vectors: usize, features: &[&'static str]) -> ProgramId { - let mut prefix = format!("#define WR_MAX_UBO_VECTORS {}\n\ - #define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n", - max_ubo_vectors, + let mut prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n", MAX_VERTEX_TEXTURE_WIDTH); for feature in features { @@ -277,46 +256,31 @@ fn create_prim_shader(name: &'static str, let program_id = device.create_program_with_prefix(name, includes, Some(prefix)); - let data_index = device.assign_ubo_binding(program_id, "Data", UBO_BIND_DATA); - - debug!("PrimShader {}: data={} max={}", name, data_index, max_ubo_vectors); + debug!("PrimShader {}", name); program_id } -fn create_clip_shader(name: &'static str, - device: &mut Device, - max_ubo_vectors: usize) -> ProgramId { - let prefix = format!("#define WR_MAX_UBO_VECTORS {}\n\ - #define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n +fn create_clip_shader(name: &'static str, device: &mut Device) -> ProgramId { + let prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n #define WR_FEATURE_TRANSFORM", - max_ubo_vectors, MAX_VERTEX_TEXTURE_WIDTH); let includes = &["prim_shared", "clip_shared"]; let program_id = device.create_program_with_prefix(name, includes, Some(prefix)); - let data_index = device.assign_ubo_binding(program_id, "Data", UBO_BIND_DATA); - - debug!("ClipShader {}: data={} max={}", name, data_index, max_ubo_vectors); + debug!("ClipShader {}", name); program_id } -fn create_clear_shader(name: &'static str, - device: &mut Device, - max_ubo_vectors: usize) -> ProgramId { - let prefix = format!("#define WR_MAX_UBO_VECTORS {}", max_ubo_vectors); - - let includes = &["shared_other"]; +fn create_clear_shader(name: &'static str, device: &mut Device) -> ProgramId { + let includes = &[]; let program_id = device.create_program_with_prefix(name, includes, - Some(prefix)); - - let data_index = device.assign_ubo_binding(program_id, "Data", UBO_BIND_DATA); - - debug!("ClearShader {}: data={} max={}", name, data_index, max_ubo_vectors); + None); + debug!("ClearShader {}", name); program_id } @@ -368,15 +332,12 @@ pub struct Renderer { tile_clear_shader: LazilyCompiledShader, - max_clear_tiles: usize, - max_prim_instances: usize, - max_cache_instances: usize, - max_clip_instances: usize, - max_blurs: usize, - notifier: Arc>>>, enable_profiler: bool, + clear_framebuffer: bool, + clear_empty_tiles: bool, + clear_color: ColorF, debug: DebugRenderer, backend_profile_counters: BackendProfileCounters, profile_counters: RendererProfileCounters, @@ -386,7 +347,10 @@ pub struct Renderer { render_targets: Vec, gpu_profile: GpuProfiler, - quad_vao_id: VAOId, + prim_vao_id: VAOId, + clear_vao_id: VAOId, + blur_vao_id: VAOId, + clip_vao_id: VAOId, layer_texture: VertexDataTexture, render_task_texture: VertexDataTexture, @@ -459,147 +423,106 @@ impl Renderer { // device-pixel ratio doesn't matter here - we are just creating resources. device.begin_frame(1.0); - let max_ubo_size = device.get_capabilities().max_ubo_size; - let max_ubo_vectors = max_ubo_size / 16; - - let max_prim_instances = get_ubo_max_len::(max_ubo_size); - let max_cache_instances = get_ubo_max_len::(max_ubo_size); - let max_clip_instances = get_ubo_max_len::(max_ubo_size); - let max_blurs = get_ubo_max_len::(max_ubo_size); - let cs_box_shadow = LazilyCompiledShader::new(ShaderKind::Cache, "cs_box_shadow", - max_cache_instances, &[], &mut device, options.precache_shaders); let cs_text_run = LazilyCompiledShader::new(ShaderKind::Cache, "cs_text_run", - max_cache_instances, &[], &mut device, options.precache_shaders); let cs_blur = LazilyCompiledShader::new(ShaderKind::Cache, "cs_blur", - max_blurs, &[], &mut device, options.precache_shaders); let cs_clip_clear = LazilyCompiledShader::new(ShaderKind::ClipCache, "cs_clip_clear", - max_clip_instances, &[], &mut device, options.precache_shaders); let cs_clip_copy = LazilyCompiledShader::new(ShaderKind::ClipCache, "cs_clip_copy", - max_clip_instances, &[], &mut device, options.precache_shaders); let cs_clip_rectangle = LazilyCompiledShader::new(ShaderKind::ClipCache, "cs_clip_rectangle", - max_clip_instances, &[], &mut device, options.precache_shaders); let cs_clip_image = LazilyCompiledShader::new(ShaderKind::ClipCache, "cs_clip_image", - max_clip_instances, &[], &mut device, options.precache_shaders); let ps_rectangle = PrimitiveShader::new("ps_rectangle", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_rectangle_clip = PrimitiveShader::new("ps_rectangle", - max_ubo_vectors, - max_prim_instances, &mut device, &[ CLIP_FEATURE ], options.precache_shaders); let ps_text_run = PrimitiveShader::new("ps_text_run", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_text_run_subpixel = PrimitiveShader::new("ps_text_run", - max_ubo_vectors, - max_prim_instances, &mut device, &[ SUBPIXEL_AA_FEATURE ], options.precache_shaders); let ps_image = PrimitiveShader::new("ps_image", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_yuv_image = PrimitiveShader::new("ps_yuv_image", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_border = PrimitiveShader::new("ps_border", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_box_shadow = PrimitiveShader::new("ps_box_shadow", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_gradient = PrimitiveShader::new("ps_gradient", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_angle_gradient = PrimitiveShader::new("ps_angle_gradient", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_cache_image = PrimitiveShader::new("ps_cache_image", - max_ubo_vectors, - max_prim_instances, &mut device, &[], options.precache_shaders); let ps_blend = LazilyCompiledShader::new(ShaderKind::Primitive, "ps_blend", - max_ubo_vectors, &[], &mut device, options.precache_shaders); let ps_composite = LazilyCompiledShader::new(ShaderKind::Primitive, "ps_composite", - max_ubo_vectors, &[], &mut device, options.precache_shaders); - let max_clear_tiles = get_ubo_max_len::(max_ubo_size); let tile_clear_shader = LazilyCompiledShader::new(ShaderKind::Clear, "ps_clear", - max_ubo_vectors, - &[], - &mut device, - options.precache_shaders); + &[], + &mut device, + options.precache_shaders); let mut texture_cache = TextureCache::new(); @@ -666,10 +589,14 @@ impl Renderer { }, ]; - let quad_vao_id = device.create_vao(VertexFormat::Triangles, None); - device.bind_vao(quad_vao_id); - device.update_vao_indices(quad_vao_id, &quad_indices, VertexUsageHint::Static); - device.update_vao_main_vertices(quad_vao_id, &quad_vertices, VertexUsageHint::Static); + let prim_vao_id = device.create_vao(VertexFormat::Triangles, mem::size_of::() as i32); + device.bind_vao(prim_vao_id); + device.update_vao_indices(prim_vao_id, &quad_indices, VertexUsageHint::Static); + device.update_vao_main_vertices(prim_vao_id, &quad_vertices, VertexUsageHint::Static); + + let clear_vao_id = device.create_vao_with_new_instances(VertexFormat::Clear, mem::size_of::() as i32, prim_vao_id); + let blur_vao_id = device.create_vao_with_new_instances(VertexFormat::Blur, mem::size_of::() as i32, prim_vao_id); + let clip_vao_id = device.create_vao_with_new_instances(VertexFormat::Clip, mem::size_of::() as i32, prim_vao_id); device.end_frame(); @@ -739,21 +666,22 @@ impl Renderer { ps_cache_image: ps_cache_image, ps_blend: ps_blend, ps_composite: ps_composite, - max_clear_tiles: max_clear_tiles, - max_prim_instances: max_prim_instances, - max_cache_instances: max_cache_instances, - max_clip_instances: max_clip_instances, - max_blurs: max_blurs, notifier: notifier, debug: debug_renderer, backend_profile_counters: BackendProfileCounters::new(), profile_counters: RendererProfileCounters::new(), profiler: Profiler::new(), enable_profiler: options.enable_profiler, + clear_framebuffer: options.clear_framebuffer, + clear_empty_tiles: options.clear_empty_tiles, + clear_color: options.clear_color, last_time: 0, render_targets: Vec::new(), gpu_profile: GpuProfiler::new(), - quad_vao_id: quad_vao_id, + prim_vao_id: prim_vao_id, + clear_vao_id: clear_vao_id, + blur_vao_id: blur_vao_id, + clip_vao_id: clip_vao_id, layer_texture: layer_texture, render_task_texture: render_task_texture, prim_geom_texture: prim_geom_texture, @@ -864,8 +792,7 @@ impl Renderer { /// /// A Frame is supplied by calling [set_root_stacking_context()][newframe]. /// [newframe]: ../../webrender_traits/struct.RenderApi.html#method.set_root_stacking_context - pub fn render(&mut self, framebuffer_size: Size2D) { - let framebuffer_size = DeviceUintSize::from_untyped(&framebuffer_size); + pub fn render(&mut self, framebuffer_size: DeviceUintSize) { if let Some(mut frame) = self.current_frame.take() { if let Some(ref mut frame) = frame.frame { let mut profile_timers = RendererProfileTimers::new(); @@ -879,17 +806,19 @@ impl Renderer { profile_timers.cpu_time.profile(|| { self.device.begin_frame(frame.device_pixel_ratio); self.gpu_profile.begin_frame(); - let _ = self.gpu_profile.add_marker(GPU_TAG_INIT); + { + let _gm = self.gpu_profile.add_marker(GPU_TAG_INIT); - self.device.disable_scissor(); - self.device.disable_depth(); - self.device.set_blend(false); + self.device.disable_scissor(); + self.device.disable_depth(); + self.device.set_blend(false); + + //self.update_shaders(); + self.update_texture_cache(); + } - //self.update_shaders(); - self.update_texture_cache(); self.draw_tile_frame(frame, &framebuffer_size); - self.device.reset_ubo(UBO_BIND_DATA); self.gpu_profile.end_frame(); }); @@ -943,7 +872,7 @@ impl Renderer { */ fn update_texture_cache(&mut self) { - let _ = GpuMarker::new("texture cache update"); + let _gm = GpuMarker::new("texture cache update"); let mut pending_texture_updates = mem::replace(&mut self.pending_texture_updates, vec![]); for update_list in pending_texture_updates.drain(..) { for update in update_list.updates { @@ -1041,31 +970,24 @@ impl Renderer { } } - fn draw_ubo_batch(&mut self, - ubo_data: &[T], - shader: ProgramId, - quads_per_item: usize, - textures: &BatchTextures, - max_prim_items: usize, - projection: &Matrix4D) { + fn draw_instanced_batch(&mut self, + data: &[T], + vao: VAOId, + shader: ProgramId, + textures: &BatchTextures, + projection: &Matrix4D) { + self.device.bind_vao(vao); self.device.bind_program(shader, &projection); - self.device.bind_vao(self.quad_vao_id); for i in 0..textures.colors.len() { let texture_id = self.resolve_source_texture(&textures.colors[i]); self.device.bind_texture(TextureSampler::color(i), texture_id); } - for chunk in ubo_data.chunks(max_prim_items) { - let ubo = self.device.create_ubo(&chunk, UBO_BIND_DATA); - - let quad_count = chunk.len() * quads_per_item; - self.device.draw_indexed_triangles_instanced_u16(6, quad_count as i32); - self.profile_counters.vertices.add(6 * (quad_count as usize)); - self.profile_counters.draw_calls.inc(); - - self.device.delete_buffer(ubo); - } + self.device.update_vao_instances(vao, data, VertexUsageHint::Stream); + self.device.draw_indexed_triangles_instanced_u16(6, data.len() as i32); + self.profile_counters.vertices.add(6 * data.len()); + self.profile_counters.draw_calls.inc(); } fn draw_target(&mut self, @@ -1074,155 +996,140 @@ impl Renderer { target_size: &DeviceSize, cache_texture: Option, should_clear: bool) { - let _ = self.gpu_profile.add_marker(GPU_TAG_SETUP_TARGET); - let dimensions = [target_size.width as u32, target_size.height as u32]; - self.device.bind_render_target(render_target, Some(dimensions)); + let projection = { + let _gm = self.gpu_profile.add_marker(GPU_TAG_SETUP_TARGET); + self.device.bind_render_target(render_target, Some(dimensions)); - self.device.set_blend(false); - self.device.set_blend_mode_alpha(); - if let Some(cache_texture) = cache_texture { - self.device.bind_texture(TextureSampler::Cache, cache_texture); - } + self.device.set_blend(false); + self.device.set_blend_mode_alpha(); + if let Some(cache_texture) = cache_texture { + self.device.bind_texture(TextureSampler::Cache, cache_texture); + } - let (color, projection) = match render_target { - Some(..) => ( - [0.0, 0.0, 0.0, 0.0], - Matrix4D::ortho(0.0, - target_size.width, - 0.0, - target_size.height, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE) - ), - None => ( - [1.0, 1.0, 1.0, 1.0], - Matrix4D::ortho(0.0, - target_size.width, - target_size.height, - 0.0, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE) - ), + let (color, projection) = match render_target { + Some(..) => ( + [0.0, 0.0, 0.0, 0.0], + Matrix4D::ortho(0.0, + target_size.width, + 0.0, + target_size.height, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE) + ), + None => ( + self.clear_color.to_array(), + Matrix4D::ortho(0.0, + target_size.width, + target_size.height, + 0.0, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE) + ), + }; + + if should_clear { + self.device.clear_color(color); + } + + projection }; - // todo(gw): remove me! - if should_clear { - self.device.clear_color(color); - } - // Draw any blurs for this target. // Blurs are rendered as a standard 2-pass // separable implementation. // TODO(gw): In the future, consider having // fast path blur shaders for common // blur radii with fixed weights. - if !target.vertical_blurs.is_empty() { - self.device.set_blend(false); - let _ = self.gpu_profile.add_marker(GPU_TAG_BLUR); - let shader = self.cs_blur.get(&mut self.device); - let max_blurs = self.max_blurs; - self.draw_ubo_batch(&target.vertical_blurs, - shader, - 1, - &BatchTextures::no_texture(), - max_blurs, - &projection); - } + if !target.vertical_blurs.is_empty() || !target.horizontal_blurs.is_empty() { + let _gm = self.gpu_profile.add_marker(GPU_TAG_BLUR); + let vao = self.blur_vao_id; - if !target.horizontal_blurs.is_empty() { self.device.set_blend(false); - let _ = self.gpu_profile.add_marker(GPU_TAG_BLUR); let shader = self.cs_blur.get(&mut self.device); - let max_blurs = self.max_blurs; - self.draw_ubo_batch(&target.horizontal_blurs, - shader, - 1, - &BatchTextures::no_texture(), - max_blurs, - &projection); + + self.draw_instanced_batch(&target.vertical_blurs, + vao, + shader, + &BatchTextures::no_texture(), + &projection); + self.draw_instanced_batch(&target.horizontal_blurs, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // Draw any box-shadow caches for this target. if !target.box_shadow_cache_prims.is_empty() { self.device.set_blend(false); - let _ = self.gpu_profile.add_marker(GPU_TAG_CACHE_BOX_SHADOW); + let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_BOX_SHADOW); + let vao = self.prim_vao_id; let shader = self.cs_box_shadow.get(&mut self.device); - let max_prim_items = self.max_cache_instances; - self.draw_ubo_batch(&target.box_shadow_cache_prims, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&target.box_shadow_cache_prims, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // Draw the clip items into the tiled alpha mask. { - let _ = self.gpu_profile.add_marker(GPU_TAG_CACHE_CLIP); + let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_CLIP); + let vao = self.clip_vao_id; // first, mark the target area as opaque //Note: not needed if we know the target is cleared with opaque self.device.set_blend(false); if !target.clip_batcher.clears.is_empty() { let shader = self.cs_clip_clear.get(&mut self.device); - let max_prim_items = self.max_clip_instances; - self.draw_ubo_batch(&target.clip_batcher.clears, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&target.clip_batcher.clears, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // alternatively, copy the contents from another task if !target.clip_batcher.copies.is_empty() { let shader = self.cs_clip_copy.get(&mut self.device); - let max_prim_items = self.max_clip_instances; - self.draw_ubo_batch(&target.clip_batcher.copies, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&target.clip_batcher.copies, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // the fast path for clear + rect, which is just the rectangle without blending if !target.clip_batcher.rectangles_noblend.is_empty() { let shader = self.cs_clip_rectangle.get(&mut self.device); - let max_prim_items = self.max_clip_instances; - self.draw_ubo_batch(&target.clip_batcher.rectangles_noblend, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&target.clip_batcher.rectangles_noblend, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // now switch to multiplicative blending self.device.set_blend(true); self.device.set_blend_mode_multiply(); // draw rounded cornered rectangles if !target.clip_batcher.rectangles.is_empty() { - let _ = GpuMarker::new("clip rectangles"); + let _gm2 = GpuMarker::new("clip rectangles"); let shader = self.cs_clip_rectangle.get(&mut self.device); - let max_prim_items = self.max_clip_instances; - self.draw_ubo_batch(&target.clip_batcher.rectangles, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&target.clip_batcher.rectangles, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } // draw image masks for (mask_texture_id, items) in target.clip_batcher.images.iter() { - let _ = GpuMarker::new("clip images"); + let _gm2 = GpuMarker::new("clip images"); let texture_id = self.resolve_source_texture(mask_texture_id); self.device.bind_texture(TextureSampler::Mask, texture_id); let shader = self.cs_clip_image.get(&mut self.device); - let max_prim_items = self.max_clip_instances; - self.draw_ubo_batch(items, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(items, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } } @@ -1236,18 +1143,18 @@ impl Renderer { self.device.set_blend(true); self.device.set_blend_mode_alpha(); - let _ = self.gpu_profile.add_marker(GPU_TAG_CACHE_TEXT_RUN); + let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_TEXT_RUN); + let vao = self.prim_vao_id; let shader = self.cs_text_run.get(&mut self.device); - let max_cache_instances = self.max_cache_instances; - self.draw_ubo_batch(&target.text_run_cache_prims, - shader, - 1, - &target.text_run_textures, - max_cache_instances, - &projection); + + self.draw_instanced_batch(&target.text_run_cache_prims, + vao, + shader, + &target.text_run_textures, + &projection); } - let _ = GpuMarker::new("alpha batches"); + let _gm2 = GpuMarker::new("alpha batches"); self.device.set_blend(false); let mut prev_blend_mode = BlendMode::None; @@ -1273,133 +1180,69 @@ impl Renderer { prev_blend_mode = batch.key.blend_mode; } - match &batch.data { - &PrimitiveBatchData::CacheImage(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_CACHE_IMAGE); - let (shader, max_prim_items) = self.ps_cache_image.get(&mut self.device, - transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + let (data, marker, shader) = match &batch.data { + &PrimitiveBatchData::CacheImage(ref data) => { + let shader = self.ps_cache_image.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_CACHE_IMAGE, shader) } - &PrimitiveBatchData::Blend(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_BLEND); + &PrimitiveBatchData::Blend(ref data) => { let shader = self.ps_blend.get(&mut self.device); - let max_prim_items = self.max_prim_instances; - self.draw_ubo_batch(ubo_data, shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + (data, GPU_TAG_PRIM_BLEND, shader) } - &PrimitiveBatchData::Composite(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_COMPOSITE); - let shader = self.ps_composite.get(&mut self.device); - let max_prim_items = self.max_prim_instances; - + &PrimitiveBatchData::Composite(ref data) => { // The composite shader only samples from sCache. debug_assert!(cache_texture.is_some()); - - self.draw_ubo_batch(ubo_data, shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); - + let shader = self.ps_composite.get(&mut self.device); + (data, GPU_TAG_PRIM_COMPOSITE, shader) } - &PrimitiveBatchData::Rectangles(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_RECT); - let (shader, max_prim_items) = if needs_clipping { + &PrimitiveBatchData::Rectangles(ref data) => { + let shader = if needs_clipping { self.ps_rectangle_clip.get(&mut self.device, transform_kind) } else { self.ps_rectangle.get(&mut self.device, transform_kind) }; - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + (data, GPU_TAG_PRIM_RECT, shader) } - &PrimitiveBatchData::Image(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_IMAGE); - let (shader, max_prim_items) = self.ps_image.get(&mut self.device, transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::Image(ref data) => { + let shader = self.ps_image.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_IMAGE, shader) } - &PrimitiveBatchData::YuvImage(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_YUV_IMAGE); - let (shader, max_prim_items) = self.ps_yuv_image.get( - &mut self.device, transform_kind - ); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::YuvImage(ref data) => { + let shader = self.ps_yuv_image.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_YUV_IMAGE, shader) } - &PrimitiveBatchData::Borders(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_BORDER); - let (shader, max_prim_items) = self.ps_border.get(&mut self.device, transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::Borders(ref data) => { + let shader = self.ps_border.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_BORDER, shader) } - &PrimitiveBatchData::BoxShadow(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_BOX_SHADOW); - let (shader, max_prim_items) = self.ps_box_shadow.get(&mut self.device, transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::BoxShadow(ref data) => { + let shader = self.ps_box_shadow.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_BOX_SHADOW, shader) } - &PrimitiveBatchData::TextRun(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_TEXT_RUN); - let (shader, max_prim_items) = match batch.key.blend_mode { + &PrimitiveBatchData::TextRun(ref data) => { + 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), }; - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + (data, GPU_TAG_PRIM_TEXT_RUN, shader) } - &PrimitiveBatchData::AlignedGradient(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_GRADIENT); - let (shader, max_prim_items) = self.ps_gradient.get(&mut self.device, transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::AlignedGradient(ref data) => { + let shader = self.ps_gradient.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_GRADIENT, shader) } - &PrimitiveBatchData::AngleGradient(ref ubo_data) => { - let _ = self.gpu_profile.add_marker(GPU_TAG_PRIM_ANGLE_GRADIENT); - let (shader, max_prim_items) = self.ps_angle_gradient.get(&mut self.device, transform_kind); - self.draw_ubo_batch(ubo_data, - shader, - 1, - &batch.key.textures, - max_prim_items, - &projection); + &PrimitiveBatchData::AngleGradient(ref data) => { + let shader = self.ps_angle_gradient.get(&mut self.device, transform_kind); + (data, GPU_TAG_PRIM_ANGLE_GRADIENT, shader) } - } + }; + + let _gm = self.gpu_profile.add_marker(marker); + let vao = self.prim_vao_id; + self.draw_instanced_batch(data, + vao, + shader, + &batch.key.textures, + &projection); } self.device.set_blend(false); @@ -1450,19 +1293,19 @@ impl Renderer { fn draw_tile_frame(&mut self, frame: &mut Frame, framebuffer_size: &DeviceUintSize) { - let _ = GpuMarker::new("tile frame draw"); + let _gm = GpuMarker::new("tile frame draw"); self.update_deferred_resolves(frame); // 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 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 _ = GpuMarker::new("debug rectangles"); + let _gm2 = GpuMarker::new("debug rectangles"); for debug_rect in frame.debug_rects.iter().rev() { self.add_debug_rect(debug_rect.rect.origin, debug_rect.rect.bottom_right(), @@ -1483,7 +1326,7 @@ impl Renderer { ORTHO_FAR_PLANE); if frame.passes.is_empty() { - self.device.clear_color([1.0, 1.0, 1.0, 1.0]); + self.device.clear_color(self.clear_color.to_array()); } else { // Add new render targets to the pool if required. let needed_targets = frame.passes.len() - 1; // framebuffer doesn't need a target! @@ -1529,7 +1372,7 @@ impl Renderer { for (pass_index, pass) in frame.passes.iter().enumerate() { let (do_clear, size, target_id) = if pass.is_framebuffer { - (needs_clear, + (self.clear_framebuffer || needs_clear, DeviceSize::new(framebuffer_size.width as f32, framebuffer_size.height as f32), None) } else { @@ -1552,19 +1395,18 @@ impl Renderer { } } - let _ = self.gpu_profile.add_marker(GPU_TAG_CLEAR_TILES); + let _gm = self.gpu_profile.add_marker(GPU_TAG_CLEAR_TILES); - // Clear tiles with no items - if !frame.clear_tiles.is_empty() { + // Tiles with no items + if self.clear_empty_tiles && !frame.empty_tiles.is_empty() { self.device.set_blend(false); + let vao = self.clear_vao_id; let shader = self.tile_clear_shader.get(&mut self.device); - let max_prim_items = self.max_clear_tiles; - self.draw_ubo_batch(&frame.clear_tiles, - shader, - 1, - &BatchTextures::no_texture(), - max_prim_items, - &projection); + self.draw_instanced_batch(&frame.empty_tiles, + vao, + shader, + &BatchTextures::no_texture(), + &projection); } self.release_external_textures(); @@ -1626,4 +1468,8 @@ pub struct RendererOptions { pub precache_shaders: bool, pub renderer_kind: RendererKind, pub enable_subpixel_aa: bool, + // TODO: this option ignores the clear color (always opaque white). + pub clear_empty_tiles: bool, + pub clear_framebuffer: bool, + pub clear_color: ColorF, } diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs index 84838b7923d2..bcb980294511 100644 --- a/gfx/webrender/src/resource_cache.rs +++ b/gfx/webrender/src/resource_cache.rs @@ -61,7 +61,7 @@ pub struct CacheItem { pub uv1: DevicePoint, } -#[derive(Clone, Hash, PartialEq, Eq, Debug)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Ord, PartialOrd)] pub struct RenderedGlyphKey { pub key: GlyphKey, pub render_mode: FontRenderMode, @@ -737,6 +737,14 @@ fn spawn_glyph_cache_thread() -> (Sender, Receiver(&'a self) -> Option<&'a StackingContext>; @@ -28,15 +28,15 @@ impl DisplayListHelpers for Vec { pub struct ScenePipeline { pub pipeline_id: PipelineId, pub epoch: Epoch, - pub viewport_size: Size2D, - pub background_color: ColorF, + pub viewport_size: LayerSize, + pub background_color: Option, } /// A complete representation of the layout bundling visible pipelines together. pub struct Scene { pub root_pipeline_id: Option, pub pipeline_map: HashMap>, - pub pipeline_sizes: HashMap>, + pub pipeline_sizes: HashMap, pub pipeline_auxiliary_lists: AuxiliaryListsMap, pub display_lists: HashMap, BuildHasherDefault>, } @@ -60,8 +60,8 @@ impl Scene { pipeline_id: PipelineId, epoch: Epoch, built_display_list: BuiltDisplayList, - background_color: ColorF, - viewport_size: Size2D, + background_color: Option, + viewport_size: LayerSize, auxiliary_lists: AuxiliaryLists) { self.pipeline_auxiliary_lists.insert(pipeline_id, auxiliary_lists); self.display_lists.insert(pipeline_id, built_display_list.all_display_items().to_vec()); diff --git a/gfx/webrender/src/tiling.rs b/gfx/webrender/src/tiling.rs index 88e2fe0dea65..07907bb6f4bd 100644 --- a/gfx/webrender/src/tiling.rs +++ b/gfx/webrender/src/tiling.rs @@ -4,7 +4,6 @@ use app_units::Au; use batch_builder::BorderSideHelpers; -use euclid::{Point2D, Rect, Size2D}; use fnv::FnvHasher; use frame::FrameId; use gpu_store::GpuStoreAddress; @@ -31,7 +30,7 @@ use std::hash::{BuildHasherDefault}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::usize; use texture_cache::TexturePage; -use util::{self, rect_from_points, MatrixHelpers, rect_from_points_f}; +use util::{self, rect_from_points, rect_from_points_f}; use util::{TransformedRect, TransformedRectKind, subtract_rect, pack_as_float}; use webrender_traits::{ColorF, FontKey, ImageKey, ImageRendering, MixBlendMode}; use webrender_traits::{BorderDisplayItem, BorderSide, BorderStyle, YuvColorSpace}; @@ -739,7 +738,7 @@ struct RenderTargetContext<'a> { pub struct RenderTarget { pub alpha_batcher: AlphaBatcher, pub clip_batcher: ClipBatcher, - pub box_shadow_cache_prims: Vec, + pub box_shadow_cache_prims: Vec, // List of text runs to be cached to this render target. // TODO(gw): For now, assume that these all come from // the same source texture id. This is almost @@ -748,7 +747,7 @@ pub struct RenderTarget { // glyphs visible. Once the future glyph / texture // cache changes land, this restriction will // be removed anyway. - pub text_run_cache_prims: Vec, + pub text_run_cache_prims: Vec, pub text_run_textures: BatchTextures, // List of blur operations to apply for this render target. pub vertical_blurs: Vec, @@ -826,12 +825,14 @@ impl RenderTarget { match prim_metadata.prim_kind { PrimitiveKind::BoxShadow => { - self.box_shadow_cache_prims.push(CachePrimitiveInstance { - task_id: render_tasks.get_task_index(&task.id, pass_index).0 as i32, + self.box_shadow_cache_prims.push(PrimitiveInstance { global_prim_id: prim_index.0 as i32, prim_address: prim_metadata.gpu_prim_index, + task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32, + clip_task_index: 0, + layer_index: 0, sub_index: 0, - user_data: [0; 4], + user_data: [0; 2], }); } PrimitiveKind::TextRun => { @@ -852,12 +853,14 @@ impl RenderTarget { self.text_run_textures = textures; for glyph_index in 0..prim_metadata.gpu_data_count { - self.text_run_cache_prims.push(CachePrimitiveInstance { - task_id: render_tasks.get_task_index(&task.id, pass_index).0 as i32, + self.text_run_cache_prims.push(PrimitiveInstance { global_prim_id: prim_index.0 as i32, prim_address: prim_metadata.gpu_prim_index, + task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32, + clip_task_index: 0, + layer_index: 0, sub_index: prim_metadata.gpu_data_address.0 + glyph_index, - user_data: [ text.resource_address.0 + glyph_index, 0, 0, 0 ], + user_data: [ text.resource_address.0 + glyph_index, 0], }); } } @@ -1384,15 +1387,6 @@ pub struct BlurCommand { padding: i32, } -#[derive(Debug)] -pub struct CachePrimitiveInstance { - global_prim_id: i32, - prim_address: GpuStoreAddress, - task_id: i32, - sub_index: i32, - user_data: [i32; 4], -} - /// A clipping primitive drawn into the clipping mask. /// Could be an image or a rectangle, which defines the /// way `address` is treated. @@ -1661,7 +1655,7 @@ impl FrameBuilderConfig { } pub struct FrameBuilder { - screen_rect: Rect, + screen_rect: LayerRect, prim_store: PrimitiveStore, cmds: Vec, debug: bool, @@ -1676,12 +1670,12 @@ pub struct FrameBuilder { /// A rendering-oriented representation of frame::Frame built by the render backend /// and presented to the renderer. pub struct Frame { - pub viewport_size: Size2D, + pub viewport_size: LayerSize, pub device_pixel_ratio: f32, pub debug_rects: Vec, pub cache_size: DeviceSize, pub passes: Vec, - pub clear_tiles: Vec, + pub empty_tiles: Vec, pub profile_counters: FrameProfileCounters, pub layer_texture_data: Vec, @@ -1983,12 +1977,11 @@ impl ScreenTile { } impl FrameBuilder { - pub fn new(viewport_size: Size2D, + pub fn new(viewport_size: LayerSize, debug: bool, config: FrameBuilderConfig) -> FrameBuilder { - let viewport_size = Size2D::new(viewport_size.width as i32, viewport_size.height as i32); FrameBuilder { - screen_rect: Rect::new(Point2D::zero(), viewport_size), + screen_rect: LayerRect::new(LayerPoint::zero(), viewport_size), layer_store: Vec::new(), prim_store: PrimitiveStore::new(), cmds: Vec::new(), @@ -2006,7 +1999,7 @@ impl FrameBuilder { let geometry = PrimitiveGeometry { local_rect: *rect, - local_clip_rect: LayerRect::from_untyped(&clip_region.main), + local_clip_rect: clip_region.main, }; let clip_source = if clip_region.is_complex() { ClipSource::Region(clip_region.clone()) @@ -2183,10 +2176,10 @@ impl FrameBuilder { pack_as_float(bottom.style as u32), ], radii: [ - LayerSize::from_untyped(&radius.top_left), - LayerSize::from_untyped(&radius.top_right), - LayerSize::from_untyped(&radius.bottom_right), - LayerSize::from_untyped(&radius.bottom_left), + radius.top_left, + radius.top_right, + radius.bottom_right, + radius.bottom_left, ], }; @@ -2805,7 +2798,7 @@ impl FrameBuilder { &mut profile_counters, device_pixel_ratio); - let mut clear_tiles = Vec::new(); + let mut empty_tiles = Vec::new(); let mut compiled_screen_tiles = Vec::new(); let mut max_passes_needed = 0; @@ -2854,7 +2847,7 @@ impl FrameBuilder { compiled_screen_tiles.push(compiled_screen_tile); } None => { - clear_tiles.push(ClearTile { + empty_tiles.push(ClearTile { rect: rect, }); } @@ -2920,7 +2913,7 @@ impl FrameBuilder { debug_rects: debug_rects, profile_counters: profile_counters, passes: passes, - clear_tiles: clear_tiles, + empty_tiles: empty_tiles, cache_size: DeviceSize::new(RENDERABLE_CACHE_SIZE as f32, RENDERABLE_CACHE_SIZE as f32), layer_texture_data: self.packed_layers.clone(), diff --git a/gfx/webrender/src/util.rs b/gfx/webrender/src/util.rs index a3ef0810e439..b7b7316431a7 100644 --- a/gfx/webrender/src/util.rs +++ b/gfx/webrender/src/util.rs @@ -64,7 +64,7 @@ impl MatrixHelpers for TypedMatrix4D { let top_right = self.transform_point(&rect.top_right()); let bottom_left = self.transform_point(&rect.bottom_left()); let bottom_right = self.transform_point(&rect.bottom_right()); - TypedRect::from_points(&top_left, &top_right, &bottom_right, &bottom_left) + TypedRect::from_points(&[top_left, top_right, bottom_right, bottom_left]) } fn can_losslessly_transform_a_2d_rect(&self) -> bool { @@ -90,12 +90,6 @@ impl MatrixHelpers for TypedMatrix4D { } pub trait RectHelpers where Self: Sized { - - fn from_points(a: &TypedPoint2D, - b: &TypedPoint2D, - c: &TypedPoint2D, - d: &TypedPoint2D) - -> Self; fn contains_rect(&self, other: &Self) -> bool; fn from_floats(x0: f32, y0: f32, x1: f32, y1: f32) -> Self; fn is_well_formed_and_nonempty(&self) -> bool; @@ -103,30 +97,6 @@ pub trait RectHelpers where Self: Sized { impl RectHelpers for TypedRect { - fn from_points(a: &TypedPoint2D, - b: &TypedPoint2D, - c: &TypedPoint2D, - d: &TypedPoint2D) -> Self { - let (mut min_x, mut min_y) = (a.x, a.y); - let (mut max_x, mut max_y) = (min_x, min_y); - for point in &[b, c, d] { - if point.x < min_x { - min_x = point.x - } - if point.x > max_x { - max_x = point.x - } - if point.y < min_y { - min_y = point.y - } - if point.y > max_y { - max_y = point.y - } - } - TypedRect::new(TypedPoint2D::new(min_x, min_y), - TypedSize2D::new(max_x - min_x, max_y - min_y)) - } - fn contains_rect(&self, other: &Self) -> bool { self.origin.x <= other.origin.x && self.origin.y <= other.origin.y && diff --git a/gfx/webrender_traits/Cargo.toml b/gfx/webrender_traits/Cargo.toml index 74bcc7447a92..83b4fceda15d 100644 --- a/gfx/webrender_traits/Cargo.toml +++ b/gfx/webrender_traits/Cargo.toml @@ -16,7 +16,7 @@ ipc = ["ipc-channel"] [dependencies] app_units = "0.3.0" byteorder = "0.5" -euclid = "0.10" +euclid = "0.10.3" gleam = "0.2" heapsize = "0.3.6" offscreen_gl_context = {version = "0.5.0", features = ["serde_serialization"]} diff --git a/gfx/webrender_traits/src/api.rs b/gfx/webrender_traits/src/api.rs index 8a1d117458b4..edf48986ff3c 100644 --- a/gfx/webrender_traits/src/api.rs +++ b/gfx/webrender_traits/src/api.rs @@ -4,13 +4,13 @@ use byteorder::{LittleEndian, WriteBytesExt}; use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender}; -use euclid::{Point2D, Size2D}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use std::cell::Cell; use {ApiMsg, ColorF, DisplayListBuilder, Epoch}; use {FontKey, IdNamespace, ImageFormat, ImageKey, NativeFontHandle, PipelineId}; use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState, ScrollLocation, ServoScrollRootId}; use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand}; +use {DeviceIntSize, LayoutPoint, LayoutSize, WorldPoint}; use VRCompositorCommand; impl RenderApiSender { @@ -155,9 +155,9 @@ impl RenderApi { /// /// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready pub fn set_root_display_list(&self, - background_color: ColorF, + background_color: Option, epoch: Epoch, - viewport_size: Size2D, + viewport_size: LayoutSize, builder: DisplayListBuilder) { let pipeline_id = builder.pipeline_id; let (display_list, auxiliary_lists) = builder.finalize(); @@ -180,13 +180,13 @@ impl RenderApi { /// /// Webrender looks for the layer closest to the user /// which has `ScrollPolicy::Scrollable` set. - pub fn scroll(&self, scroll_location: ScrollLocation, cursor: Point2D, phase: ScrollEventPhase) { + pub fn scroll(&self, scroll_location: ScrollLocation, cursor: WorldPoint, phase: ScrollEventPhase) { let msg = ApiMsg::Scroll(scroll_location, cursor, phase); self.api_sender.send(msg).unwrap(); } pub fn scroll_layers_with_scroll_root_id(&self, - new_scroll_origin: Point2D, + new_scroll_origin: LayoutPoint, pipeline_id: PipelineId, scroll_root_id: ServoScrollRootId) { let msg = ApiMsg::ScrollLayersWithScrollId(new_scroll_origin, pipeline_id, scroll_root_id); @@ -199,8 +199,8 @@ impl RenderApi { } /// Translates a point from viewport coordinates to layer space - pub fn translate_point_to_layer_space(&self, point: &Point2D) - -> (Point2D, PipelineId) { + pub fn translate_point_to_layer_space(&self, point: &WorldPoint) + -> (LayoutPoint, PipelineId) { let (tx, rx) = channel::msg_channel().unwrap(); let msg = ApiMsg::TranslatePointToLayerSpace(*point, tx); self.api_sender.send(msg).unwrap(); @@ -214,7 +214,7 @@ impl RenderApi { rx.recv().unwrap() } - pub fn request_webgl_context(&self, size: &Size2D, attributes: GLContextAttributes) + pub fn request_webgl_context(&self, size: &DeviceIntSize, attributes: GLContextAttributes) -> Result<(WebGLContextId, GLLimits), String> { let (tx, rx) = channel::msg_channel().unwrap(); let msg = ApiMsg::RequestWebGLContext(*size, attributes, tx); @@ -222,7 +222,7 @@ impl RenderApi { rx.recv().unwrap() } - pub fn resize_webgl_context(&self, context_id: WebGLContextId, size: &Size2D) { + pub fn resize_webgl_context(&self, context_id: WebGLContextId, size: &DeviceIntSize) { let msg = ApiMsg::ResizeWebGLContext(context_id, *size); self.api_sender.send(msg).unwrap(); } diff --git a/gfx/webrender_traits/src/display_item.rs b/gfx/webrender_traits/src/display_item.rs index b6c240964456..81d54522a97a 100644 --- a/gfx/webrender_traits/src/display_item.rs +++ b/gfx/webrender_traits/src/display_item.rs @@ -3,55 +3,55 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use display_list::AuxiliaryListsBuilder; -use euclid::{Point2D, Rect, Size2D}; use {BorderRadius, BorderDisplayItem, ClipRegion, ColorF, ComplexClipRegion}; use {FontKey, ImageKey, PipelineId, ScrollLayerId, ScrollLayerInfo, ServoScrollRootId}; use {ImageMask, ItemRange}; +use {LayoutSize, LayoutPoint, LayoutRect}; impl BorderDisplayItem { - pub fn top_left_inner_radius(&self) -> Size2D { - Size2D::new((self.radius.top_left.width - self.left.width).max(0.0), - (self.radius.top_left.height - self.top.width).max(0.0)) + pub fn top_left_inner_radius(&self) -> LayoutSize { + LayoutSize::new((self.radius.top_left.width - self.left.width).max(0.0), + (self.radius.top_left.height - self.top.width).max(0.0)) } - pub fn top_right_inner_radius(&self) -> Size2D { - Size2D::new((self.radius.top_right.width - self.right.width).max(0.0), - (self.radius.top_right.height - self.top.width).max(0.0)) + pub fn top_right_inner_radius(&self) -> LayoutSize { + LayoutSize::new((self.radius.top_right.width - self.right.width).max(0.0), + (self.radius.top_right.height - self.top.width).max(0.0)) } - pub fn bottom_left_inner_radius(&self) -> Size2D { - Size2D::new((self.radius.bottom_left.width - self.left.width).max(0.0), - (self.radius.bottom_left.height - self.bottom.width).max(0.0)) + pub fn bottom_left_inner_radius(&self) -> LayoutSize { + LayoutSize::new((self.radius.bottom_left.width - self.left.width).max(0.0), + (self.radius.bottom_left.height - self.bottom.width).max(0.0)) } - pub fn bottom_right_inner_radius(&self) -> Size2D { - Size2D::new((self.radius.bottom_right.width - self.right.width).max(0.0), - (self.radius.bottom_right.height - self.bottom.width).max(0.0)) + pub fn bottom_right_inner_radius(&self) -> LayoutSize { + LayoutSize::new((self.radius.bottom_right.width - self.right.width).max(0.0), + (self.radius.bottom_right.height - self.bottom.width).max(0.0)) } } impl BorderRadius { pub fn zero() -> BorderRadius { BorderRadius { - top_left: Size2D::new(0.0, 0.0), - top_right: Size2D::new(0.0, 0.0), - bottom_left: Size2D::new(0.0, 0.0), - bottom_right: Size2D::new(0.0, 0.0), + top_left: LayoutSize::new(0.0, 0.0), + top_right: LayoutSize::new(0.0, 0.0), + bottom_left: LayoutSize::new(0.0, 0.0), + bottom_right: LayoutSize::new(0.0, 0.0), } } pub fn uniform(radius: f32) -> BorderRadius { BorderRadius { - top_left: Size2D::new(radius, radius), - top_right: Size2D::new(radius, radius), - bottom_left: Size2D::new(radius, radius), - bottom_right: Size2D::new(radius, radius), + top_left: LayoutSize::new(radius, radius), + top_right: LayoutSize::new(radius, radius), + bottom_left: LayoutSize::new(radius, radius), + bottom_right: LayoutSize::new(radius, radius), } } } impl ClipRegion { - pub fn new(rect: &Rect, + pub fn new(rect: &LayoutRect, complex: Vec, image_mask: Option, auxiliary_lists_builder: &mut AuxiliaryListsBuilder) @@ -63,7 +63,7 @@ impl ClipRegion { } } - pub fn simple(rect: &Rect) -> ClipRegion { + pub fn simple(rect: &LayoutRect) -> ClipRegion { ClipRegion { main: *rect, complex: ItemRange::empty(), @@ -94,11 +94,15 @@ impl ColorF { a: self.a, } } + + pub fn to_array(&self) -> [f32; 4] { + [self.r, self.g, self.b, self.a] + } } impl ComplexClipRegion { /// Create a new complex clip region. - pub fn new(rect: Rect, radii: BorderRadius) -> ComplexClipRegion { + pub fn new(rect: LayoutRect, radii: BorderRadius) -> ComplexClipRegion { ComplexClipRegion { rect: rect, radii: radii, @@ -107,7 +111,7 @@ impl ComplexClipRegion { //TODO: move to `util` module? /// Return a maximum aligned rectangle that is fully inside the clip region. - pub fn get_inner_rect(&self) -> Option> { + pub fn get_inner_rect(&self) -> Option { let k = 0.3; //roughly higher than `1.0 - sqrt(0.5)` let xl = self.rect.origin.x + k * self.radii.top_left.width.max(self.radii.bottom_left.width); @@ -118,7 +122,7 @@ impl ComplexClipRegion { let yb = self.rect.origin.y + self.rect.size.height - k * self.radii.bottom_left.height.max(self.radii.bottom_right.height); if xl <= xr && yt <= yb { - Some(Rect::new(Point2D::new(xl, yt), Size2D::new(xr-xl, yb-yt))) + Some(LayoutRect::new(LayoutPoint::new(xl, yt), LayoutSize::new(xr-xl, yb-yt))) } else { None } diff --git a/gfx/webrender_traits/src/display_list.rs b/gfx/webrender_traits/src/display_list.rs index 0107d37b9d6c..b27cec370ab5 100644 --- a/gfx/webrender_traits/src/display_list.rs +++ b/gfx/webrender_traits/src/display_list.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; -use euclid::{Matrix4D, Point2D, Rect, Size2D}; use std::mem; use std::slice; use {AuxiliaryLists, AuxiliaryListsDescriptor, BorderDisplayItem, BorderRadius}; @@ -15,6 +14,7 @@ use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange, MixBlendM use {PushScrollLayerItem, PushStackingContextDisplayItem, RectangleDisplayItem, ScrollLayerId}; use {ScrollPolicy, ServoScrollRootId, SpecificDisplayItem, StackingContext, TextDisplayItem}; use {WebGLContextId, WebGLDisplayItem, YuvImageDisplayItem}; +use {LayoutTransform, LayoutPoint, LayoutRect, LayoutSize}; impl BuiltDisplayListDescriptor { pub fn size(&self) -> usize { @@ -72,7 +72,7 @@ impl DisplayListBuilder { } pub fn push_rect(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, color: ColorF) { let item = RectangleDisplayItem { @@ -89,10 +89,10 @@ impl DisplayListBuilder { } pub fn push_image(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, - stretch_size: Size2D, - tile_spacing: Size2D, + stretch_size: LayoutSize, + tile_spacing: LayoutSize, image_rendering: ImageRendering, key: ImageKey) { let item = ImageDisplayItem { @@ -112,7 +112,7 @@ impl DisplayListBuilder { } pub fn push_yuv_image(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, y_key: ImageKey, u_key: ImageKey, @@ -131,7 +131,7 @@ impl DisplayListBuilder { } pub fn push_webgl_canvas(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, context_id: WebGLContextId) { let item = WebGLDisplayItem { @@ -148,7 +148,7 @@ impl DisplayListBuilder { } pub fn push_text(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, glyphs: Vec, font_key: FontKey, @@ -181,7 +181,7 @@ impl DisplayListBuilder { } pub fn push_border(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, left: BorderSide, top: BorderSide, @@ -206,10 +206,10 @@ impl DisplayListBuilder { } pub fn push_box_shadow(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, - box_bounds: Rect, - offset: Point2D, + box_bounds: LayoutRect, + offset: LayoutPoint, color: ColorF, blur_radius: f32, spread_radius: f32, @@ -235,10 +235,10 @@ impl DisplayListBuilder { } pub fn push_gradient(&mut self, - rect: Rect, + rect: LayoutRect, clip: ClipRegion, - start_point: Point2D, - end_point: Point2D, + start_point: LayoutPoint, + end_point: LayoutPoint, stops: Vec) { let item = GradientDisplayItem { start_point: start_point, @@ -255,13 +255,13 @@ impl DisplayListBuilder { self.list.push(display_item); } - pub fn push_stacking_context(&mut self, + pub fn push_stacking_context(&mut self, scroll_policy: ScrollPolicy, - bounds: Rect, + bounds: LayoutRect, clip: ClipRegion, z_index: i32, - transform: &Matrix4D, - perspective: &Matrix4D, + transform: &LayoutTransform, + perspective: &LayoutTransform, mix_blend_mode: MixBlendMode, filters: Vec) { let stacking_context = StackingContext { @@ -278,7 +278,7 @@ impl DisplayListBuilder { item: SpecificDisplayItem::PushStackingContext(PushStackingContextDisplayItem { stacking_context: stacking_context }), - rect: Rect::zero(), + rect: LayoutRect::zero(), clip: clip, }; self.list.push(item); @@ -287,15 +287,15 @@ impl DisplayListBuilder { pub fn pop_stacking_context(&mut self) { let item = DisplayItem { item: SpecificDisplayItem::PopStackingContext, - rect: Rect::zero(), - clip: ClipRegion::simple(&Rect::zero()), + rect: LayoutRect::zero(), + clip: ClipRegion::simple(&LayoutRect::zero()), }; self.list.push(item); } pub fn push_scroll_layer(&mut self, - clip: Rect, - content_size: Size2D, + clip: LayoutRect, + content_size: LayoutSize, scroll_root_id: ServoScrollRootId) { let scroll_layer_id = self.next_scroll_layer_id; self.next_scroll_layer_id += 1; @@ -308,7 +308,7 @@ impl DisplayListBuilder { let item = DisplayItem { item: SpecificDisplayItem::PushScrollLayer(item), rect: clip, - clip: ClipRegion::simple(&Rect::zero()), + clip: ClipRegion::simple(&LayoutRect::zero()), }; self.list.push(item); } @@ -316,13 +316,13 @@ impl DisplayListBuilder { pub fn pop_scroll_layer(&mut self) { let item = DisplayItem { item: SpecificDisplayItem::PopScrollLayer, - rect: Rect::zero(), - clip: ClipRegion::simple(&Rect::zero()), + rect: LayoutRect::zero(), + clip: ClipRegion::simple(&LayoutRect::zero()), }; self.list.push(item); } - pub fn push_iframe(&mut self, rect: Rect, clip: ClipRegion, pipeline_id: PipelineId) { + 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, @@ -332,7 +332,7 @@ impl DisplayListBuilder { } pub fn new_clip_region(&mut self, - rect: &Rect, + rect: &LayoutRect, complex: Vec, image_mask: Option) -> ClipRegion { diff --git a/gfx/webrender_traits/src/stacking_context.rs b/gfx/webrender_traits/src/stacking_context.rs index d47decc64a46..2740b9f4b4c2 100644 --- a/gfx/webrender_traits/src/stacking_context.rs +++ b/gfx/webrender_traits/src/stacking_context.rs @@ -3,15 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use display_list::AuxiliaryListsBuilder; -use euclid::{Matrix4D, Rect}; use {FilterOp, MixBlendMode, ScrollPolicy, StackingContext}; +use {LayoutTransform, LayoutRect}; impl StackingContext { pub fn new(scroll_policy: ScrollPolicy, - bounds: Rect, + bounds: LayoutRect, z_index: i32, - transform: &Matrix4D, - perspective: &Matrix4D, + transform: &LayoutTransform, + perspective: &LayoutTransform, mix_blend_mode: MixBlendMode, filters: Vec, auxiliary_lists_builder: &mut AuxiliaryListsBuilder) diff --git a/gfx/webrender_traits/src/types.rs b/gfx/webrender_traits/src/types.rs index 34b2566be086..9d05d8b6d5a5 100644 --- a/gfx/webrender_traits/src/types.rs +++ b/gfx/webrender_traits/src/types.rs @@ -9,7 +9,6 @@ use app_units::Au; use channel::{PayloadSender, MsgSender}; #[cfg(feature = "nightly")] use core::nonzero::NonZero; -use euclid::{Matrix4D, Point2D, Rect, Size2D}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use std::sync::Arc; @@ -39,20 +38,20 @@ pub enum ApiMsg { /// /// After receiving this message, WebRender will read the display list, followed by the /// auxiliary lists, from the payload channel. - SetRootDisplayList(ColorF, + SetRootDisplayList(Option, Epoch, PipelineId, - Size2D, + LayoutSize, BuiltDisplayListDescriptor, AuxiliaryListsDescriptor), SetRootPipeline(PipelineId), - Scroll(ScrollLocation, Point2D, ScrollEventPhase), - ScrollLayersWithScrollId(Point2D, PipelineId, ServoScrollRootId), + Scroll(ScrollLocation, WorldPoint, ScrollEventPhase), + ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId), TickScrollingBounce, - TranslatePointToLayerSpace(Point2D, MsgSender<(Point2D, PipelineId)>), + TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>), GetScrollLayerState(MsgSender>), - RequestWebGLContext(Size2D, GLContextAttributes, MsgSender>), - ResizeWebGLContext(WebGLContextId, Size2D), + RequestWebGLContext(DeviceIntSize, GLContextAttributes, MsgSender>), + ResizeWebGLContext(WebGLContextId, DeviceIntSize), WebGLCommand(WebGLContextId, WebGLCommand), GenerateFrame, // WebVR commands that must be called in the WebGL render thread. @@ -98,10 +97,10 @@ pub struct BorderDisplayItem { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct BorderRadius { - pub top_left: Size2D, - pub top_right: Size2D, - pub bottom_left: Size2D, - pub bottom_right: Size2D, + pub top_left: LayoutSize, + pub top_right: LayoutSize, + pub bottom_left: LayoutSize, + pub bottom_right: LayoutSize, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] @@ -134,8 +133,8 @@ pub enum BoxShadowClipMode { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct BoxShadowDisplayItem { - pub box_bounds: Rect, - pub offset: Point2D, + pub box_bounds: LayoutRect, + pub offset: LayoutPoint, pub color: ColorF, pub blur_radius: f32, pub spread_radius: f32, @@ -176,13 +175,13 @@ known_heap_size!(0, ColorF); #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct ImageMask { pub image: ImageKey, - pub rect: Rect, + pub rect: LayoutRect, pub repeat: bool, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct ClipRegion { - pub main: Rect, + pub main: LayoutRect, pub complex: ItemRange, pub image_mask: Option, } @@ -190,7 +189,7 @@ pub struct ClipRegion { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct ComplexClipRegion { /// The boundaries of the rectangle. - pub rect: Rect, + pub rect: LayoutRect, /// Border radii of this rectangle. pub radii: BorderRadius, } @@ -198,7 +197,7 @@ pub struct ComplexClipRegion { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct DisplayItem { pub item: SpecificDisplayItem, - pub rect: Rect, + pub rect: LayoutRect, pub clip: ClipRegion, } @@ -225,17 +224,17 @@ pub enum FilterOp { Sepia(f32), } -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, Ord, PartialOrd)] pub struct FontKey(u32, u32); -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)] pub enum FontRenderMode { Mono, Alpha, Subpixel, } -#[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize)] +#[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. @@ -275,8 +274,8 @@ pub struct GlyphInstance { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct GradientDisplayItem { - pub start_point: Point2D, - pub end_point: Point2D, + pub start_point: LayoutPoint, + pub end_point: LayoutPoint, pub stops: ItemRange, } @@ -295,7 +294,7 @@ pub struct PushStackingContextDisplayItem { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct PushScrollLayerItem { - pub content_size: Size2D, + pub content_size: LayoutSize, pub id: ScrollLayerId, } @@ -310,8 +309,8 @@ pub struct IdNamespace(pub u32); #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct ImageDisplayItem { pub image_key: ImageKey, - pub stretch_size: Size2D, - pub tile_spacing: Size2D, + pub stretch_size: LayoutSize, + pub tile_spacing: LayoutSize, pub image_rendering: ImageRendering, } @@ -424,7 +423,7 @@ pub struct RenderApiSender { pub trait RenderNotifier: Send { fn new_frame_ready(&mut self); fn new_scroll_frame_ready(&mut self, composite_needed: bool); - fn pipeline_size_changed(&mut self, pipeline_id: PipelineId, size: Option>); + fn pipeline_size_changed(&mut self, pipeline_id: PipelineId, size: Option); } // Trait to allow dispatching functions to a specific thread or event loop. @@ -478,7 +477,7 @@ pub enum ScrollLayerInfo { pub struct ScrollLayerState { pub pipeline_id: PipelineId, pub scroll_root_id: ServoScrollRootId, - pub scroll_offset: Point2D, + pub scroll_offset: LayoutPoint, } #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] @@ -490,7 +489,7 @@ pub enum ScrollPolicy { #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub enum ScrollLocation { /// Scroll by a certain amount. - Delta(Point2D), + Delta(LayoutPoint), /// Scroll to very top of element. Start, /// Scroll to very bottom of element. @@ -520,10 +519,10 @@ pub enum SpecificDisplayItem { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct StackingContext { pub scroll_policy: ScrollPolicy, - pub bounds: Rect, + pub bounds: LayoutRect, pub z_index: i32, - pub transform: Matrix4D, - pub perspective: Matrix4D, + pub transform: LayoutTransform, + pub perspective: LayoutTransform, pub mix_blend_mode: MixBlendMode, pub filters: ItemRange, } diff --git a/gfx/webrender_traits/src/units.rs b/gfx/webrender_traits/src/units.rs index 4bfa149e0d4c..7e1d5a040f82 100644 --- a/gfx/webrender_traits/src/units.rs +++ b/gfx/webrender_traits/src/units.rs @@ -32,6 +32,15 @@ pub type DeviceRect = TypedRect; pub type DevicePoint = TypedPoint2D; pub type DeviceSize = TypedSize2D; +/// Geometry in a stacking context's local coordinate space (logical pixels). +/// +/// For now layout pixels are equivalent to layer pixels, but it may change. +pub type LayoutPixel = LayerPixel; + +pub type LayoutRect = LayerRect; +pub type LayoutPoint = LayerPoint; +pub type LayoutSize = LayerSize; + /// Geometry in a layer's local coordinate space (logical pixels). #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct LayerPixel; @@ -65,6 +74,7 @@ pub type WorldSize = TypedSize2D; pub type WorldPoint4D = TypedPoint4D; +pub type LayoutTransform = TypedMatrix4D; pub type LayerTransform = TypedMatrix4D; pub type LayerToScrollTransform = TypedMatrix4D; pub type ScrollToLayerTransform = TypedMatrix4D; @@ -80,3 +90,4 @@ pub fn device_length(value: f32, device_pixel_ratio: f32) -> DeviceIntLength { pub fn as_scroll_parent_rect(rect: &LayerRect) -> ScrollLayerRect { ScrollLayerRect::from_untyped(&rect.to_untyped()) } +