Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image mask support #445

Merged
merged 2 commits into from Oct 26, 2016
Merged

Image mask support #445

merged 2 commits into from Oct 26, 2016

Conversation

@kvark
Copy link
Member

kvark commented Oct 17, 2016

Closes #405

I'm not completely sure if this is the right approach, hoping to get some review/feedback to proceed. The API and logic works for me with wr_sample, although the implementation lacks a lot of features to support, like image repeating and layout transformations.


This change is Reviewable

@glennw
Copy link
Member

glennw commented Oct 17, 2016

@kvark Thanks! The general idea here seems good - the public API looks fine to me.

In terms of implementation, I try to avoid using uniform variables whenever possible, to simplify how the batching code works and reduce batch breaks. Instead, what I'd suggest is adding fields to the Clip struct in tiling.rs, and modifying the code in prim_shared to fetch the data from there. That way, there shouldn't be any need to change the batching code at all.

Let me know if that doesn't make sense or you foresee any issues with that :)

@kvark
Copy link
Member Author

kvark commented Oct 18, 2016

@glennw thanks for taking a look!
I've actually considered that (passing via Clip) but then thought that since the image itself is being passed as a uniform sampler, it doesn't make sense to pass the associated data per batch.
Now that I think of it though, the image we pass is an atlas, so it makes perfect sense to have different source/dest rectangles per batch given that these refer to different sub-images within the atlas.
I'll implement the proposed change and get back to you ;)

@glennw
Copy link
Member

glennw commented Oct 18, 2016

@kvark Yep, that's right - we put (almost) everything in an atlas, so it should batch together nicely :)

@bors-servo
Copy link
Contributor

bors-servo commented Oct 18, 2016

The latest upstream changes (presumably #432) made this pull request unmergeable. Please resolve the merge conflicts.

@kvark kvark force-pushed the kvark:image_mask branch from a264c17 to 483b23d Oct 21, 2016
@kvark
Copy link
Member Author

kvark commented Oct 21, 2016

Rebased now, the implementation follows the route you laid out - passing the clip rectangles via the batch data instead of uniforms.

@bors-servo
Copy link
Contributor

bors-servo commented Oct 24, 2016

The latest upstream changes (presumably #461) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Member

glennw left a comment

Looks pretty good, just a few minor issues / questions. I rebased it locally on my machine to test with, there was only a couple of minor conflicts to fix up.

@@ -5,6 +5,8 @@

flat varying vec4 vClipRect;
flat varying vec4 vClipRadius;
flat varying vec4 vClipMaskUvRect;
flat varying vec4 vClipMaskScreenRect;

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

We should probably rename this to be something like vClipMaskLocalRect, since (I think) it's in the local space of the primitive rectangle?

This comment has been minimized.

Copy link
@kvark

kvark Oct 24, 2016

Author Member

fixed

return rect;
}

struct MaskRect {

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

Could we rename these fields to be a bit more descriptive? Perhaps uv_rect and local_mask_rect or something like that?

This comment has been minimized.

Copy link
@kvark

kvark Oct 24, 2016

Author Member

fixed

@@ -206,12 +209,19 @@ impl ClipCorner {
}

#[derive(Debug, Clone)]
pub struct MaskRect {

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

Perhaps rename this to ImageMaskInfo or something like that?

This comment has been minimized.

Copy link
@kvark

kvark Oct 24, 2016

Author Member

fixed

@@ -552,6 +553,11 @@ impl Renderer {
let data64_texture = VertexDataTexture::new(&mut device);
let data128_texture = VertexDataTexture::new(&mut device);

let dummy_mask_texture = device.create_texture_ids(1)[0];

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

I wonder if this will cause unnecessary batch breaks when there are clips that don't have masks. We could probably insert a dummy mask into the atlas instead of creating a separate texture. But that doesn't matter for now, we can do it as a follow up if it's an issue.

This comment has been minimized.

Copy link
@kvark

kvark Oct 24, 2016

Author Member

I had a hard time figuring out how to properly assign a default masking texture for this case. Ended up introducing DummyResources struct to store the white texture as well the opaque one (which were previously forgotten but still created). Let me know if there is a better solution please.

@@ -702,6 +704,23 @@ impl RenderTask {
pub const SCREEN_TILE_SIZE: i32 = 64;
pub const RENDERABLE_CACHE_SIZE: DevicePixel = DevicePixel(2048);

/// Per-batch clipping info merged with the mask image.
#[derive(Clone, Debug)]
pub struct MaskedClip {

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

Instead of introducing a new structure here, could we just add the fields/struct to the Clip structure? The Clip structure already handles simple / complex clips, it seems like it's probably reasonable to make the Clip structure able to handle any number of clip types. If we do that, we won't need to modify the API of all the FrameBuilder methods.

This comment has been minimized.

Copy link
@kvark

kvark Oct 24, 2016

Author Member

MaskedClip is a part of the Clip, so moving the fields in there directly would break the API as much regardless. The reason I even introduced this was to pack both rectangles into a single 32 byte gpu block, instead of having a 16 byte pad after each.

@kvark kvark force-pushed the kvark:image_mask branch from 23062f5 to 88653ac Oct 24, 2016
Copy link
Member

glennw left a comment

Nearly there! :)

vec2 local_pos = vPos;
#endif

alpha = min(alpha, do_clip(local_pos));

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

This contains a do_clip() call which fails to compile.

This comment has been minimized.

Copy link
@kvark

kvark Oct 25, 2016

Author Member

oh, nicely spotted!

@@ -676,7 +693,7 @@ impl Renderer {
fn enable_msaa(&self, _: bool) {
}

#[cfg(any(target_os = "windows", unix))]
#[cfg(any(target_os = "linux", target_os = "windows", target_os = "macos"))]

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

Mistake during rebase to change this?

This comment has been minimized.

Copy link
@kvark

kvark Oct 25, 2016

Author Member

weird indeed, fixed


/// Per-batch clipping info merged with the mask image.
#[derive(Clone, Debug)]
pub struct MaskedClip {

This comment has been minimized.

Copy link
@glennw

glennw Oct 24, 2016

Member

I'm still not sure about having this struct. Could we have something like:

struct Clip {
  // existing clip rect and corners
  pub mask: Option<MaskImageSource>,
}

And then use that to construct the data to be put in the gpu blocks during prim prepare / cache?

I might be missing something as I haven't actually tried this - but it sounds like it might be a simpler API if it works.

This comment has been minimized.

Copy link
@kvark

kvark Oct 25, 2016

Author Member

I'm following the existing style in here. Clip structure (contrary to ClipRegion) is supposed to map semi-directly to the GPU. At least it seems it should, given that the shader side has the same structs (Clip, ClipRect, ClipCorner).
If I add Option<MaskImageSource>, that would make it inconsistent, since:

pub enum MaskImageSource {
    User(ImageKey),
    Renderer(TextureId),
}

This comment has been minimized.

Copy link
@glennw

glennw Oct 25, 2016

Member

I can see your point about the consistency aspect of the structure internals, but I think having the public API type for FrameBuilder be called Clip is important. How about as a compromise we keep the structure layout as is, but rename Clip -> ClipGpu and make it private, and rename MaskedClip -> Clip?

This comment has been minimized.

Copy link
@kvark

kvark Oct 25, 2016

Author Member

agreed, fixed now

oFragColor = vColor * vec4(1, 1, 1, alpha);

#ifdef WR_FEATURE_TRANSFORM

This comment has been minimized.

Copy link
@kvark

kvark Oct 25, 2016

Author Member

@glennw
Looks like we were multiplying the alpha twice. I assume this was a mistake.

@glennw
Copy link
Member

glennw commented Oct 25, 2016

@kvark Looks good! Let's squash and get this merged :)

@kvark
Copy link
Member Author

kvark commented Oct 25, 2016

Do you want a single commit? Or 2-3?

On Oct 25, 2016, at 16:54, Glenn Watson notifications@github.com wrote:

@kvark Looks good! Let's squash and get this merged :)


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@glennw
Copy link
Member

glennw commented Oct 25, 2016

@kvark The smallest number of commits that make sense as individual commits. 2-3 is fine if that makes sense.

kvark added 2 commits Oct 20, 2016
Includes the new DummyResource struct as well as a non-clipping gradient shader.
@kvark kvark force-pushed the kvark:image_mask branch from 526eaaf to 1e33028 Oct 25, 2016
@glennw
Copy link
Member

glennw commented Oct 25, 2016

@bors-servo
Copy link
Contributor

bors-servo commented Oct 25, 2016

📌 Commit 1e33028 has been approved by glennw

@glennw
glennw approved these changes Oct 25, 2016
@bors-servo
Copy link
Contributor

bors-servo commented Oct 26, 2016

Testing commit 1e33028 with merge f13e95b...

bors-servo added a commit that referenced this pull request Oct 26, 2016
Image mask support

Closes #405

I'm not completely sure if this is the right approach, hoping to get some review/feedback to proceed. The API and logic works for me with `wr_sample`, although the implementation lacks a lot of features to support, like image repeating and layout transformations.

<!-- 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/445)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Oct 26, 2016

☀️ Test successful - status-travis

@bors-servo bors-servo merged commit 1e33028 into servo:master Oct 26, 2016
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@kvark kvark deleted the kvark:image_mask branch Oct 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.