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 overdraw as option to GAPID UI framebuffer view #2070

Merged
merged 7 commits into from
Jul 27, 2018

Conversation

sean-purcell
Copy link
Contributor

Previously the feature was only accessible through gapit screenshot. Looks like:
screenshot from 2018-07-18 17-49-12

Two issues:

  1. The rescaling is somewhat hacky as currently done (specifically stencil images that set the normalized flag get rescaled), the goal is to take the stencil bytes and scale them from [0, max] to [0, 255], while also storing the original values of the data to show at the bottom when mousing over the overdraw image (so that the maximum overdrawn area of the screen is shown as white, but the actual value can be queried). @pmuetschard @ben-clayton @AWoloszyn What would be the best way to architect this in gapic? Thanks

  2. It's currently using the depth buffer icon, I would appreciate some guidance on how to generate a good icon for this.

@ben-clayton
Copy link
Contributor

goal is to take the stencil bytes and scale them from [0, max] to [0, 255]

Are there any stencil formats greater than 8 bit?

Let's assume there are - then GAPIC already has a tonemapper which does what you're after.

That said, in my past experiences, stencil buffers are more commonly used for bit-masks than scalar values. Maybe we should offer up a way to show / hide individual bits in the UI?

@sean-purcell
Copy link
Contributor Author

There are on Vulkan, and my understanding is that its generally 8 bits on GLES as well, but not required. Ok I'll look into the tonemapper, thanks. So here I'm trying to show specifically the overdraw information, which just happens to have a stencil format, not a general stencil view. I agree that that should have some sort of bitmask view.

@sean-purcell sean-purcell changed the title Add overdraw as option to GAPID UI framebuffer view (WIP) Add overdraw as option to GAPID UI framebuffer view Jul 19, 2018
@ben-clayton
Copy link
Contributor

So here I'm trying to show specifically the overdraw information, which just happens to have a stencil format

In that case, I think it makes sense to translate from Stencil to a new stream Count Channel in GAPIS.
That way the client has enough metadata to understand what it is dealing with, and can offer up more sensible ways of visualizing this.

@sean-purcell
Copy link
Contributor Author

Sure, sounds good.

@sean-purcell
Copy link
Contributor Author

Looks like this now:
image

@sean-purcell sean-purcell changed the title (WIP) Add overdraw as option to GAPID UI framebuffer view Add overdraw as option to GAPID UI framebuffer view Jul 19, 2018
@ben-clayton
Copy link
Contributor

Looks like this now

The histogram / HDR slider looks a bit empty - is the client handling the new count component?

@ben-clayton ben-clayton requested a review from pmuetschard July 23, 2018 15:19
@ben-clayton
Copy link
Contributor

Once you have lots of overdraw going on, spotting the gradient changes might be challenging.
Similar tools have addressed this by coloring the first few counts with different colors (like a heatmap) and then saturating the counts greater a certain threshold (configurable by the user).
The tonemapper handles the threshold aspect, but I'm not sure how discoverable it would be if there were a few pixels somewhere that had a crazy number of overdraws.
Not suggesting that you need to change anything right now - just something to think about.

@sean-purcell
Copy link
Contributor Author

The histogram / HDR slider looks a bit empty - is the client handling the new count component?

Fixed, I forgot to update the channel for count image binning.

The tonemapper handles the threshold aspect, but I'm not sure how discoverable it would be if there were a few pixels somewhere that had a crazy number of overdraws.

Hmm, good point, currently the only way to investigate minor differences is to adjust things with the histogram slider. It could be made more discoverable by maybe opening the histogram by default in overdraw mode?

@ben-clayton
Copy link
Contributor

It could be made more discoverable by maybe opening the histogram by default in overdraw mode?

Could be a little in-your-face. I was thinking that maybe the default should be a tonemap range of 0-10, and you can expand this range if you wanted to. Not have this default interfere with the user's preferences might be tricky though (user adjusts limits, clicks to the next frame, gets annoyed that the limits are reset)

@sean-purcell
Copy link
Contributor Author

I was thinking that maybe the default should be a tonemap range of 0-10

Ok, that sounds reasonable.

(user adjusts limits, clicks to the next frame, gets annoyed that the limits are reset)

The limit resetting is the current behaviour with depth and colour images, is it annoying that it gets reset there as well?

@ben-clayton
Copy link
Contributor

is it annoying that it gets reset there as well?

It can be yes.

@sean-purcell
Copy link
Contributor Author

It can be yes.

Maybe that behaviour should be changed in general then, e.g. have ImagePanel.ImageComponent store preferences for each image type and use those instead of histogram.getInitialRange if available when the image is changed.

@ben-clayton
Copy link
Contributor

However, the logic for a non-annoying experience is not simple.

  • If you're switching between two HDR images of the same 'subject' you probably want to keep the tonemapping sliders the same (so that there isn't a jump in settings).
  • If you're switching between an HDR to non-HDR image, then you do want to adjust the sliders.

I'm not sure what the perfect solution is here (if there is one).

@sean-purcell
Copy link
Contributor Author

That's true. At least in Vulkan, one potentially reasonable option is to maintain the settings as long as they're switching around within a single subpass, as those are all rendering to the same framebuffer attachments.

@@ -276,6 +305,9 @@ public static Format from(Image.Format format) {
boolean color = isColorFormat(format);
int channels = getChannelCount(format, color ? COLOR_CHANNELS : DEPTH_CHANNELS);
boolean is8bit = are8BitsEnough(format, color ? COLOR_CHANNELS : DEPTH_CHANNELS);
if (isCountFormat(format) && is8bit) {
Copy link
Member

Choose a reason for hiding this comment

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

is8bit is still computed by only looking at the color or depth channels

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/**
* @return true if this image should be tone-mapped when displayed.
*/
public boolean isCount();
Copy link
Member

Choose a reason for hiding this comment

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

Combine isHDR and isCount into an enum, since there really are only 3 possibilities:
LDR, HDR and Count.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -80,7 +88,7 @@ public Range getInitialRange(double snapThreshold) {
* @param high if true, return the upper limit on the percentile's bin, otherwise the lower limit.
* @return the absolute pixel value at the specified percentile in the histogram.
*/
private double getPercentile(int percentile, boolean high) {
public double getPercentile(int percentile, boolean high) {
Copy link
Member

Choose a reason for hiding this comment

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

Leave private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/**
* An {@link ArrayImage} that represents an 8bit count image.
*/
public static class Count8Image extends Luminance8Image {
Copy link
Member

Choose a reason for hiding this comment

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

Don't extend Luminance8Image, you are overriding practically all methods anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -428,7 +433,7 @@ public PixelInfo getInfo() {
return info;
}

private static class Pixel implements PixelValue {
protected static class Pixel implements PixelValue {
Copy link
Member

Choose a reason for hiding this comment

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

Leave private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

return true;
}

protected static class Pixel implements PixelValue {
Copy link
Member

Choose a reason for hiding this comment

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

This should be private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

private final int count;

public Pixel(byte count) {
this.count = count & 0xFF;
Copy link
Member

Choose a reason for hiding this comment

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

Use UnsignedBytes.toInt instead of & 0xFF for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -723,7 +789,7 @@ public double getAlphaMax() {

@Override
public boolean isNormalized() {
return true;
return normalized;
Copy link
Member

Choose a reason for hiding this comment

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

sigh... this really just duplicated isHDR() (well, the inverse, but still...). Feel free to leave as is, or incorporate with the change of isHDR and isCount into an enum as I'm requesting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

- Combine isHDR and isCount into a single enum, as they are mutually
exclusive
- Other minor fixes
@sean-purcell
Copy link
Contributor Author

@pmuetschard @ben-clayton PTAL

@pmuetschard pmuetschard merged commit 3234d0d into google:master Jul 27, 2018
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.

3 participants