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

Add support for caching render tasks across frames and display lists. #2284

Merged
merged 1 commit into from Jan 15, 2018

Conversation

@glennw
Copy link
Member

glennw commented Jan 11, 2018

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):

  • Support caching of RGBA8 render tasks.
  • Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
  • Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).

This change is Reviewable

@glennw
Copy link
Member Author

glennw commented Jan 11, 2018

r? @kvark

I still need to do a try run - will kick one off shortly.

As you may expect, this has some quite significant performance and power saving wins. Next step for box shadows is to optimize the clip masks and the application of the box shadows (which are still way slower than they need to be).

@glennw glennw force-pushed the glennw:cache-bs-6 branch from 5e7dc58 to 6099487 Jan 11, 2018
@kvark
Copy link
Member

kvark commented Jan 11, 2018

Implementation looks good to me, minus a few non-blocking concerns. Amazing work!

Concept-wise, this triggers an alarm. Treating some parts of the texture cache as renderable while mostly using it as a texel storage is not going to make driver's life easier for determining the internal representation of the image (tiling mode, color compression, also cache flush points).

I suppose moving the persistent rendered results into separate texture(s) is not a great option in terms of batching and complexity. Perhaps, we'll investigate later if doing a blit from our temporary render target into texture cache is better than rendering into the texture cache directly. Blit requires the TRANSFER_DST flags in Vulkan, which we already need for copying stuff from CPU into the texture cache (with PBOs), so blitting would not incur any additional requirements for the image layout and such.


Reviewed 21 of 21 files at r1.
Review status: all files reviewed at latest revision, 8 unresolved discussions.


webrender/res/brush_image.glsl, line 65 at r1 (raw file):

    vUv.z = blur_task.common_data.texture_layer_index;
    vec2 texture_size = vec2(textureSize(sColor0, 0).xy);
    vColor = blur_task.color;

could also unconditionally have vColor output to merge these paths


webrender/src/batch.rs, line 472 at r1 (raw file):

            let batch = self.batch_list.get_suitable_batch(key, pic_metadata.screen_rect.as_ref().expect("bug"));

            let render_task_id = match *pic.surface.as_ref().expect("BUG: no surface for splitting") {

nit: can we match pic.surface and move the panic from expect here to a match arm?


webrender/src/render_task.rs, line 660 at r1 (raw file):

}

pub struct RenderTaskCache {

please add some comments explain what this is


webrender/src/render_task.rs, line 693 at r1 (raw file):

        // from here so that this hash map doesn't
        // grow indefinitely!
        self.entries.retain(|_, value| {

can we do this by asking the texture cache if each particular entry has been evicted (as opposed to introducing FRAMES_BEFORE_EVICTION here)?


webrender/src/render_task.rs, line 712 at r1 (raw file):

                              .entry(key)
                              .or_insert_with(|| {
                                RenderTaskCacheEntry {

nit: or_insert would probably be as good here


webrender/src/render_task.rs, line 723 at r1 (raw file):

            // Invoke user closure to get render task chain
            // to draw this into the texture cache.
            let (render_task_id, user_data) = f(render_tasks);

note to self: refactor to avoid passing a closure there, e.g. by having a temporary object/builder


webrender/src/texture_cache.rs, line 429 at r1 (raw file):

                 DeviceUintRect::new(origin, entry.size))
            }
            None => panic!("BUG: handle not requested earlier in frame"),

could also go with as_ref().expect(...) at the beginning, matching the arm body


webrender/src/tiling.rs, line 519 at r1 (raw file):

}

impl RenderTarget for TextureCacheRenderTarget {

that's one weird implementation... only having add_task doing something meaningful.
Do we have to have this implementation?


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Jan 11, 2018

Review status: 15 of 21 files reviewed at latest revision, 8 unresolved discussions.


webrender/res/brush_image.glsl, line 65 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

could also unconditionally have vColor output to merge these paths

Merged the two similar branches with some ifdef hackery.


webrender/src/batch.rs, line 472 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

nit: can we match pic.surface and move the panic from expect here to a match arm?

Done.


webrender/src/render_task.rs, line 660 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

please add some comments explain what this is

Done.


webrender/src/render_task.rs, line 693 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

can we do this by asking the texture cache if each particular entry has been evicted (as opposed to introducing FRAMES_BEFORE_EVICTION here)?

Good idea. I added is_allocated to the texture cache to check if a handle is valid, and remove items based on that.


webrender/src/render_task.rs, line 712 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

nit: or_insert would probably be as good here

Done.


webrender/src/texture_cache.rs, line 429 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

could also go with as_ref().expect(...) at the beginning, matching the arm body

Done.


webrender/src/tiling.rs, line 519 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

that's one weird implementation... only having add_task doing something meaningful.
Do we have to have this implementation?

Good point - fixed.


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Jan 11, 2018

@kvark Thanks for the review! All comments addressed, I think.

I also wondered about whether it makes sense to blit from the intermediate cache in to the texture cache instead of drawing directly. It should be trivial to make it work like that in the future if profiling shows it to be worthwhile.

@kvark
Copy link
Member

kvark commented Jan 11, 2018

:lgtm:


Reviewed 6 of 6 files at r2.
Review status: all files reviewed at latest revision, 1 unresolved discussion.


Comments from Reviewable

@kvark
Copy link
Member

kvark commented Jan 11, 2018

@bors-servo
Copy link
Contributor

bors-servo commented Jan 11, 2018

📌 Commit 369c7b8 has been approved by kvark

@bors-servo
Copy link
Contributor

bors-servo commented Jan 12, 2018

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

@glennw glennw force-pushed the glennw:cache-bs-6 branch from 369c7b8 to a4b5641 Jan 13, 2018
@glennw
Copy link
Member Author

glennw commented Jan 13, 2018

Rebased and squashed.

@bors-servo r=kvark

@bors-servo
Copy link
Contributor

bors-servo commented Jan 13, 2018

📌 Commit a4b5641 has been approved by kvark

@bors-servo
Copy link
Contributor

bors-servo commented Jan 13, 2018

Testing commit a4b5641 with merge 45657e1...

bors-servo added a commit that referenced this pull request Jan 13, 2018
Add support for caching render tasks across frames and display lists.

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):
 * Support caching of RGBA8 render tasks.
 * Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
 * Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).

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

bors-servo commented Jan 13, 2018

💔 Test failed - status-travis

@glennw
Copy link
Member Author

glennw commented Jan 13, 2018

@bors-servo retry

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

🔒 Merge conflict

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

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

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):
 * Support caching of RGBA8 render tasks.
 * Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
 * Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).
@glennw glennw force-pushed the glennw:cache-bs-6 branch from a4b5641 to 606bb8b Jan 14, 2018
@glennw
Copy link
Member Author

glennw commented Jan 14, 2018

@bors-servo r=kvark

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

📌 Commit 606bb8b has been approved by kvark

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

Testing commit 606bb8b with merge 331f89c...

bors-servo added a commit that referenced this pull request Jan 14, 2018
Add support for caching render tasks across frames and display lists.

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):
 * Support caching of RGBA8 render tasks.
 * Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
 * Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).

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

bors-servo commented Jan 14, 2018

💔 Test failed - status-travis

@kvark
Copy link
Member

kvark commented Jan 14, 2018

@bors-servo retry

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

Testing commit 606bb8b with merge ab70848...

bors-servo added a commit that referenced this pull request Jan 14, 2018
Add support for caching render tasks across frames and display lists.

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):
 * Support caching of RGBA8 render tasks.
 * Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
 * Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).

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

bors-servo commented Jan 14, 2018

💔 Test failed - status-travis

@glennw
Copy link
Member Author

glennw commented Jan 14, 2018

@bors-servo retry

@bors-servo
Copy link
Contributor

bors-servo commented Jan 14, 2018

Testing commit 606bb8b with merge c238f5d...

bors-servo added a commit that referenced this pull request Jan 14, 2018
Add support for caching render tasks across frames and display lists.

This patch adds the infrastructure required to allow render tasks
to be rendered into the texture cache, where they can be stored
and referenced across multiple frames.

Since the cache key is based on the contents of the task itself,
the cache items remain valid even when a new display list is provided,
so long as the content of the cached task is the same. When the cache
is determined to be valid, the render task is just drawn as a simple
image, rather than executing the complex render task chain used to
build the output.

Convert box-shadows to make use of this new feature. When a new
box-shadow is required, the render task chain is set up to draw the
minimal box-shadow, and blur it. The blurred result is then stored in
the texture cache, available for use on this and subsequent frames.

Since items are drawn into the texture cache, this will also help
with batching in the future, as we collapse more items to be able to
use a simple shader that draws an image from the texture cache.

Remove blur regions since they are no longer used or required.
Remove old render task sharing within a single frame, it's redundant now.

TODO (as future work):
 * Support caching of RGBA8 render tasks.
 * Convert other tasks (e.g. clips, drop-shadows) to use cacheable tasks.
 * Use this as basis for optimizing rendering of static Pictures (e.g. a picture with a filter chain + image).

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

bors-servo commented Jan 14, 2018

💔 Test failed - status-travis

@glennw
Copy link
Member Author

glennw commented Jan 15, 2018

gwbors says this is good enough, even with travis failures.

@glennw glennw merged commit f1cecd7 into servo:master Jan 15, 2018
2 of 4 checks passed
2 of 4 checks passed
homu Test failed
Details
code-review/reviewable 6 files, 1 discussion left (glennw, kvark)
Details
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
@glennw glennw deleted the glennw:cache-bs-6 branch Jan 15, 2018
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

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