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

Introduce SourceTexture, an abstraction for location of source textures. #554

Merged
merged 2 commits into from
Nov 14, 2016

Conversation

glennw
Copy link
Member

@glennw glennw commented Nov 11, 2016

This allows the backend thread to work with textures that have
been allocation by the texture cache, via webgl or an external
source transparently. The native texture ID is resolved by the
rendering thread as requited.

Specifically:

  • Add SourceTexture, an abstraction for the location of a source texture.
  • Add CacheTextureID, an ID for a texture cache managed texture.
    • This removes the need to allocate a pool of textures up front.
  • Remove unused batch.rs file.
  • Remove the concept of "raw textures" from device.rs
    • The native texture ID is stored inside the SourceTexture enum now.
  • Remove some unused functions in device.rs.

This change is Reviewable

@glennw
Copy link
Member Author

glennw commented Nov 11, 2016

I figured I'd prototype adding the source texture -> resolving idea I had today, and it worked out quite well I think. Thoughts @nical @kvark @JerryShih ?

This removes the use of TextureId from the backend thread, using SourceTexture instead, which is resolved to TextureId in the rendering thread. I haven't implemented the external texture support, but I've left a couple of TODO notes where I would expect it to fit in.

This also doesn't handle the idea of getting UV rects in the renderer thread, but that can be sorted out when we do the actual external image support. Does this look reasonable to you guys?

@glennw
Copy link
Member Author

glennw commented Nov 11, 2016

This is basically taking @nical 's external texture branch, and extending it to handle webgl textures, and fixing up the texture cache ID pool at the same time.

@glennw
Copy link
Member Author

glennw commented Nov 11, 2016

@nical @JerryShih @kvark I have pushed a WIP follow up commit to this 3fe9214 here.

This commit is a messy, untested, but mostly complete implementation of how I think external images + custom UV rects could work.

The first part of the idea is that primitives no longer store their UV rect directly - there is a GpuDataStore for all UV rectangles, just like there is for many other GPU types. This means that vertex shaders fetch their UV rect from here, and primitives allocate a slot inside this array when they are first added.

Next, the add_image() API gets extended to support adding different types of images (raw bytes, or external, with some arbitrary key).

Now, when we resolve images from the texture cache to get their UV rect, if it finds an external texture, instead of storing a UV rect directly, it creates a DeferredResolve item, noting the external source texture and the index in the UV rects array where the UV rect actually belongs.

Finally, that array of DeferredResolves are passed to the render thread with each frame. The first thing the renderer does is iterate that list, invoking the user callback to get the uv rect and / or texture id. Once that is done, it can patch the resource rects array, just before it uploads to the GPU.

The part I haven't implemented is the actual callbacks (there are two panics where the callbacks would be invoked).

Apart from that, I think the ideal should work. Any thoughts on whether this seems like a reasonable API / implementation from your perspective?

@glennw
Copy link
Member Author

glennw commented Nov 11, 2016

The nice thing about this approach is that the render thread doesn't really have to know much more about the backend thread than it already does. The only real new functionality on the render thread is to run through a list of deferred resolve structures, run a callback, and patch an array with the result.

Copy link
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I don't find it rough, just got a few minor points.

@@ -18,11 +18,46 @@ use std::hash::BuildHasherDefault;
use std::i32;
use std::path::PathBuf;
use std::sync::Arc;
use std::usize;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could combine with std::i32

pub struct CacheTextureId(pub usize);

impl CacheTextureId {
pub fn invalid() -> CacheTextureId {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are abusing the invalid() concept a bit too much. Rust way is Option, and we already have SourceTexture::invalid variant. Perhaps, we can get away without CacheTextureId::invalid?

@@ -337,26 +372,17 @@ pub enum RenderTargetMode {

#[derive(Debug)]
pub enum TextureUpdateDetails {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as this enum becomes trivial, maybe we can turn it into a struct?

// map from cache texture ID to native texture.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct CacheTextureId(pub usize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the long term, I'd like to have types like this opaque (non-public internals), but this can (and should) be done later on as a separate change


// A vectors for fast resolves of texture cache IDs to
// native texture IDs.
cache_texture_id_map: Vec<Option<TextureId>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great to have a few words in the comment saying why it's an Option<> inside

@@ -373,6 +373,10 @@ pub struct Renderer {
/// Used to dispatch functions to the main thread's event loop.
/// Required to allow GLContext sharing in some implementations like WGL.
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>,

// A vectors for fast resolves of texture cache IDs to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use real doc comments ///

&SourceTexture::Invalid => TextureId::invalid(),
&SourceTexture::WebGL(id) => TextureId::new(id),
&SourceTexture::TextureCache(index) => {
self.cache_texture_id_map[index.0].unwrap()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably better to switch to expect()

@nical
Copy link
Contributor

nical commented Nov 12, 2016

Looks good! (both this PR and the draft deferred UV implementation).

@glennw
Copy link
Member Author

glennw commented Nov 14, 2016

@kvark Thanks for the review, comments addressed and pushed.

r? @pcwalton

@bors-servo
Copy link
Contributor

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

This allows the backend thread to work with textures that have
been allocation by the texture cache, via webgl or an external
source transparently. The native texture ID is resolved by the
rendering thread as requited.

Specifically:

* Add SourceTexture, an abstraction for the location of a source texture.
* Add CacheTextureID, an ID for a texture cache managed texture.
    * This removes the need to allocate a pool of textures up front.
* Remove unused batch.rs file.
* Remove the concept of "raw textures" from device.rs
    * The native texture ID is stored inside the SourceTexture enum now.
* Remove some unused functions in device.rs.
Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with that if you want

// the new ID there.
debug_assert!(self.cache_texture_id_map[cache_texture_index].is_none());
self.cache_texture_id_map[cache_texture_index] = Some(texture_id);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use Vec::grow_set() to make this a one-liner if you wanted, but up to you

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like grow_set was deprecated (rust-lang/rust#17029) - it doesn't seem to be available in stable rust.

@glennw
Copy link
Member Author

glennw commented Nov 14, 2016

@bors-servo r=pcwalton

@bors-servo
Copy link
Contributor

📌 Commit 3345d0b has been approved by pcwalton

@bors-servo
Copy link
Contributor

⌛ Testing commit 3345d0b with merge 916f46e...

bors-servo pushed a commit that referenced this pull request Nov 14, 2016
Introduce SourceTexture, an abstraction for location of source textures.

This allows the backend thread to work with textures that have
been allocation by the texture cache, via webgl or an external
source transparently. The native texture ID is resolved by the
rendering thread as requited.

Specifically:

* Add SourceTexture, an abstraction for the location of a source texture.
* Add CacheTextureID, an ID for a texture cache managed texture.
    * This removes the need to allocate a pool of textures up front.
* Remove unused batch.rs file.
* Remove the concept of "raw textures" from device.rs
    * The native texture ID is stored inside the SourceTexture enum now.
* Remove some unused functions in device.rs.

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

☀️ Test successful - status-travis

@bors-servo bors-servo merged commit 3345d0b into servo:master Nov 14, 2016
@glennw glennw deleted the ext branch November 14, 2016 22:45
glennw pushed a commit to glennw/saltfs that referenced this pull request Dec 13, 2016
kvark has make several important contributions to webrender,
both as a reviewer and committer. He also has significant
Rust experience previously as the author of gfx-rs.

Some examples of recent reviews:

servo/webrender#546
servo/webrender#523
servo/webrender#561
servo/webrender#554
bors-servo pushed a commit to servo/saltfs that referenced this pull request Dec 13, 2016
[Proposal] Give @kvark reviewer privileges.

kvark has make several important contributions to webrender,
both as a reviewer and committer. He also has significant
Rust experience previously as the author of gfx-rs.

Some examples of recent reviews:

servo/webrender#546
servo/webrender#523
servo/webrender#561
servo/webrender#554

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/saltfs/551)
<!-- Reviewable:end -->
Coder206 pushed a commit to Coder206/saltfs that referenced this pull request Apr 22, 2017
kvark has make several important contributions to webrender,
both as a reviewer and committer. He also has significant
Rust experience previously as the author of gfx-rs.

Some examples of recent reviews:

servo/webrender#546
servo/webrender#523
servo/webrender#561
servo/webrender#554
choudhary001 pushed a commit to choudhary001/saltfs that referenced this pull request May 27, 2017
kvark has make several important contributions to webrender,
both as a reviewer and committer. He also has significant
Rust experience previously as the author of gfx-rs.

Some examples of recent reviews:

servo/webrender#546
servo/webrender#523
servo/webrender#561
servo/webrender#554
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants