Skip to content

Commit bcb5968

Browse files
author
bors-servo
authored
Auto merge of #561 - glennw:external-images, r=pcwalton
Add an API for providing external images. This allows applications to provide images without supplying the image bytes up front. This can be useful if the application doesn't have the bytes available immediately (e.g. video decoding) or wants to manage the buffer allocation and reduce memory copies. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/561) <!-- Reviewable:end -->
2 parents 3f6da44 + afb0f06 commit bcb5968

15 files changed

+376
-140
lines changed

sample/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use gleam::gl;
99
use std::path::PathBuf;
1010
use std::ffi::CStr;
1111
use webrender_traits::{AuxiliaryListsBuilder, ColorF, Epoch, GlyphInstance};
12-
use webrender_traits::{ImageFormat, PipelineId, RendererKind};
12+
use webrender_traits::{ImageData, ImageFormat, PipelineId, RendererKind};
1313
use std::fs::File;
1414
use std::io::Read;
1515
use std::env;
@@ -134,7 +134,7 @@ fn main() {
134134

135135
let clip_region = {
136136
let mask = webrender_traits::ImageMask {
137-
image: api.add_image(2, 2, None, ImageFormat::A8, vec![0,80, 180, 255]),
137+
image: api.add_image(2, 2, None, ImageFormat::A8, ImageData::Raw(vec![0,80, 180, 255])),
138138
rect: Rect::new(Point2D::new(75.0, 75.0), Size2D::new(100.0, 100.0)),
139139
repeat: false,
140140
};

webrender/res/cs_text_run.vs.glsl

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ void main(void) {
1313
TextRun text = fetch_text_run(cpi.specific_prim_index);
1414
Glyph glyph = fetch_glyph(cpi.sub_index);
1515
PrimitiveGeometry pg = fetch_prim_geometry(cpi.global_prim_index);
16+
ResourceRect res = fetch_resource_rect(cpi.user_data.x);
1617

1718
// Glyphs size is already in device-pixels.
1819
// The render task origin is in device-pixels. Offset that by
1920
// the glyph offset, relative to its primitive bounding rect.
20-
vec2 size = glyph.uv_rect.zw - glyph.uv_rect.xy;
21+
vec2 size = res.uv_rect.zw - res.uv_rect.xy;
2122
vec2 origin = task.data0.xy + uDevicePixelRatio * (glyph.offset.xy - pg.local_rect.xy);
2223
vec4 local_rect = vec4(origin, size);
2324

2425
vec2 texture_size = vec2(textureSize(sColor0, 0));
25-
vec2 st0 = glyph.uv_rect.xy / texture_size;
26-
vec2 st1 = glyph.uv_rect.zw / texture_size;
26+
vec2 st0 = res.uv_rect.xy / texture_size;
27+
vec2 st1 = res.uv_rect.zw / texture_size;
2728

2829
vec2 pos = mix(local_rect.xy,
2930
local_rect.xy + local_rect.zw,

webrender/res/prim_shared.glsl

+23-9
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ uniform sampler2D sData16;
5757
uniform sampler2D sData32;
5858
uniform sampler2D sData64;
5959
uniform sampler2D sData128;
60+
uniform sampler2D sResourceRects;
6061

6162
ivec2 get_fetch_uv(int index, int vecs_per_item) {
6263
int items_per_row = WR_MAX_VERTEX_TEXTURE_WIDTH / vecs_per_item;
@@ -208,16 +209,14 @@ GradientStop fetch_gradient_stop(int index) {
208209

209210
struct Glyph {
210211
vec4 offset;
211-
vec4 uv_rect;
212212
};
213213

214214
Glyph fetch_glyph(int index) {
215215
Glyph glyph;
216216

217-
ivec2 uv = get_fetch_uv_2(index);
217+
ivec2 uv = get_fetch_uv_1(index);
218218

219-
glyph.offset = texelFetchOffset(sData32, uv, 0, ivec2(0, 0));
220-
glyph.uv_rect = texelFetchOffset(sData32, uv, 0, ivec2(1, 0));
219+
glyph.offset = texelFetchOffset(sData16, uv, 0, ivec2(0, 0));
221220

222221
return glyph;
223222
}
@@ -324,19 +323,22 @@ struct CachePrimitiveInstance {
324323
int specific_prim_index;
325324
int render_task_index;
326325
int sub_index;
326+
ivec4 user_data;
327327
};
328328

329329
CachePrimitiveInstance fetch_cache_instance(int index) {
330330
CachePrimitiveInstance cpi;
331331

332-
int offset = index * 1;
332+
int offset = index * 2;
333333

334334
ivec4 data0 = int_data[offset + 0];
335+
ivec4 data1 = int_data[offset + 1];
335336

336337
cpi.global_prim_index = data0.x;
337338
cpi.specific_prim_index = data0.y;
338339
cpi.render_task_index = data0.z;
339340
cpi.sub_index = data0.w;
341+
cpi.user_data = data1;
340342

341343
return cpi;
342344
}
@@ -536,6 +538,20 @@ TransformVertexInfo write_transform_vertex(vec4 instance_rect,
536538

537539
#endif //WR_FEATURE_TRANSFORM
538540

541+
struct ResourceRect {
542+
vec4 uv_rect;
543+
};
544+
545+
ResourceRect fetch_resource_rect(int index) {
546+
ResourceRect rect;
547+
548+
ivec2 uv = get_fetch_uv_1(index);
549+
550+
rect.uv_rect = texelFetchOffset(sResourceRects, uv, 0, ivec2(0, 0));
551+
552+
return rect;
553+
}
554+
539555
struct Rectangle {
540556
vec4 color;
541557
};
@@ -565,18 +581,16 @@ TextRun fetch_text_run(int index) {
565581
}
566582

567583
struct Image {
568-
vec4 st_rect; // Location of the image texture in the texture atlas.
569584
vec4 stretch_size_and_tile_spacing; // Size of the actual image and amount of space between
570585
// tiled instances of this image.
571586
};
572587

573588
Image fetch_image(int index) {
574589
Image image;
575590

576-
ivec2 uv = get_fetch_uv_2(index);
591+
ivec2 uv = get_fetch_uv_1(index);
577592

578-
image.st_rect = texelFetchOffset(sData32, uv, 0, ivec2(0, 0));
579-
image.stretch_size_and_tile_spacing = texelFetchOffset(sData32, uv, 0, ivec2(1, 0));
593+
image.stretch_size_and_tile_spacing = texelFetchOffset(sData16, uv, 0, ivec2(0, 0));
580594

581595
return image;
582596
}

webrender/res/ps_image.vs.glsl

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
void main(void) {
77
Primitive prim = load_primitive(gl_InstanceID);
88
Image image = fetch_image(prim.prim_index);
9+
ResourceRect res = fetch_resource_rect(prim.user_data.x);
910

1011
#ifdef WR_FEATURE_TRANSFORM
1112
TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
@@ -26,8 +27,8 @@ void main(void) {
2627

2728
// vUv will contain how many times this image has wrapped around the image size.
2829
vec2 texture_size = vec2(textureSize(sColor0, 0));
29-
vec2 st0 = image.st_rect.xy / texture_size;
30-
vec2 st1 = image.st_rect.zw / texture_size;
30+
vec2 st0 = res.uv_rect.xy / texture_size;
31+
vec2 st1 = res.uv_rect.zw / texture_size;
3132

3233
vTextureSize = st1 - st0;
3334
vTextureOffset = st0;

webrender/res/ps_text_run.vs.glsl

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ void main(void) {
77
Primitive prim = load_primitive(gl_InstanceID);
88
TextRun text = fetch_text_run(prim.prim_index);
99
Glyph glyph = fetch_glyph(prim.sub_index);
10-
vec4 local_rect = vec4(glyph.offset.xy, (glyph.uv_rect.zw - glyph.uv_rect.xy) / uDevicePixelRatio);
10+
ResourceRect res = fetch_resource_rect(prim.user_data.x);
11+
12+
vec4 local_rect = vec4(glyph.offset.xy, (res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio);
1113

1214
#ifdef WR_FEATURE_TRANSFORM
1315
TransformVertexInfo vi = write_transform_vertex(local_rect,
@@ -28,8 +30,8 @@ void main(void) {
2830
write_clip(vi.global_clamped_pos, prim.clip_area);
2931

3032
vec2 texture_size = vec2(textureSize(sColor0, 0));
31-
vec2 st0 = glyph.uv_rect.xy / texture_size;
32-
vec2 st1 = glyph.uv_rect.zw / texture_size;
33+
vec2 st0 = res.uv_rect.xy / texture_size;
34+
vec2 st1 = res.uv_rect.zw / texture_size;
3335

3436
vColor = text.color;
3537
vUv = mix(st0, st1, f);

webrender/src/device.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,11 @@ impl Device {
13661366
if u_data128 != -1 {
13671367
gl::uniform_1i(u_data128, TextureSampler::Data128 as i32);
13681368
}
1369+
1370+
let u_resource_rects = gl::get_uniform_location(program.id, "sResourceRects");
1371+
if u_resource_rects != -1 {
1372+
gl::uniform_1i(u_resource_rects, TextureSampler::ResourceRects as i32);
1373+
}
13691374
}
13701375
}
13711376
}

webrender/src/internal_types.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::sync::Arc;
2020
use tiling;
2121
use webrender_traits::{Epoch, ColorF, PipelineId};
2222
use webrender_traits::{ImageFormat, MixBlendMode, NativeFontHandle};
23-
use webrender_traits::{ScrollLayerId, WebGLCommand};
23+
use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand};
2424

2525
// An ID for a texture that is owned by the
2626
// texture cache module. This can include atlases
@@ -45,9 +45,7 @@ pub enum SourceTexture {
4545
Invalid,
4646
TextureCache(CacheTextureId),
4747
WebGL(u32), // Is actually a gl::GLuint
48-
49-
// TODO(gw): Implement external image support via callback
50-
//External(i32),
48+
External(ExternalImageId),
5149
}
5250

5351
pub enum GLContextHandleWrapper {
@@ -203,6 +201,7 @@ pub enum TextureSampler {
203201
Layers,
204202
RenderTasks,
205203
Geometry,
204+
ResourceRects,
206205
}
207206

208207
impl TextureSampler {

webrender/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,5 @@ extern crate offscreen_gl_context;
121121
extern crate byteorder;
122122
extern crate rayon;
123123

124+
pub use renderer::{ExternalImage, ExternalImageSource, ExternalImageHandler};
124125
pub use renderer::{Renderer, RendererOptions};

0 commit comments

Comments
 (0)