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

Expose separate rows from PlaneSlice #1035

Merged
merged 15 commits into from
Feb 27, 2019
Merged

Expose separate rows from PlaneSlice #1035

merged 15 commits into from
Feb 27, 2019

Conversation

rom1v
Copy link
Collaborator

@rom1v rom1v commented Feb 23, 2019

Currently, many functions access rectangular regions of planes (spanning multiple rows) via a primitive slice to the whole plane along with the stride information.

This strategy is not compatible with tiling, since this borrows the memory belonging to other tiles.

This is basically what I explained in #631 (comment).

Therefore, only expose separate rows in PlaneSlice.

Concretely, here are the changes from the caller point of view:

// get a specific row

// before
let row = plane_slice.as_slice()[y * stride..(y + 1) * stride];
// or if we don't care about the end
let row = plane_slice.as_slice()[y * stride..];

// after
let row = &plane_slice[y];
// get a component value

// before
let value = plane_slice.as_slice()[y * stride + x];

// after
let value = plane_slice[y][x];
// iterate over rows

// before
for row in plane_slice.as_slice().chunks(stride).take(height) {
    let _first_four_values = &row[..4];
}

// after
for row in plane_slice.rows_iter() {
    let _first_four_values = &row[..4];
}

Note that in itself, it does not solve the incompatibility with tiles (PlaneSlice itself still borrows the whole plane primitive slice). This is only the first step to remove all usages of raw slice + stride information, so that we can then replace PlaneSlice by a tile-specific "plane region" structure which does not borrow memory outside the tile (cf #821).

For now, I only submit changes for PlaneSlice. I will submit similar changes for PlaneMutSlice once I get feedbacks on this one (and when it's finished).

EDIT: #1043 does the same for PlaneMutSlice

Copy link
Collaborator

@lu-zero lu-zero left a comment

Choose a reason for hiding this comment

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

The two unsafe usages could be wrapped in a different way later, the rest looks pretty neat already :)

@coveralls
Copy link
Collaborator

coveralls commented Feb 23, 2019

Coverage Status

Coverage increased (+0.2%) to 82.026% when pulling 993af98 on rom1v:planeslice.23 into 7fd3938 on xiph:master.

@rom1v rom1v force-pushed the planeslice.23 branch 2 times, most recently from 5d12ae6 to 739deda Compare February 25, 2019 14:08
Many functions currently using a primitive slice along with the stride
information will accept a Plane(Mut)Slice instead.

As a consequence, we will often need to get a Plane(Mut)Slice instance
without any offset, so add a convenient function which do not require a
&PlaneOffset parameter.
Currently, many functions access rectangular regions of planes (spanning
multiple rows) via a primitive slice to the whole plane along with the
stride information.

This strategy is not compatible with tiling, since this borrows the
memory belonging to other tiles.

As a first step, add PlaneSlice methods to access rows separetely.

See <xiph#631 (comment)>.
Implement trait Index to access PlaneSlice rows as if it was a
two-dimensional array.

That way, we can write:

    let row = &plane_slice[5];
    let value = plane_slice[5][3];
Add rows_iter() to iterate over PlaneSlice rows.
The util function convert_slice_2d() operates on a slice with stride
information. It will become incompatible with PlaneSlice which will not
expose a multi-rows slice anymore (see
<xiph#631 (comment)>).

To keep it generic enough, we don't want to use a PlaneSlice wrapper for
every call, so make the function use raw pointers (and unsafe).

Note: this commit changes indentation for unsafe blocks, so the diff is
more understable with "git show -b".
The function run_filter() operates on a slice with stride information.

Since it is sometimes called on primitive arrays that do not belong to a
plane, or with "arbitrary" stride (e.g. 1, which is different from the
plane stride), do not make it accept PlaneSlice.

Instead, make it use raw pointers (and unsafe).
Remove as_slice() and similar methods from PlaneSlice which expose
slices spanning multiple rows.
@tdaede
Copy link
Collaborator

tdaede commented Feb 27, 2019

This looks excellent!

@lu-zero lu-zero merged commit f3aa26a into xiph:master Feb 27, 2019
type Item = &'a [T];

fn next(&mut self) -> Option<Self::Item> {
let remaining = self.ps.plane.cfg.height as isize - self.ps.y + self.next_row as isize;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oops, parentheses missing:

let remaining = self.ps.plane.cfg.height as isize - (self.ps.y + self.next_row as isize);

It's fixed in my PlaneMutSlice pull request #1043.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Weird that it didn't get picked up in tests.

@rom1v rom1v mentioned this pull request Mar 18, 2019
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.

None yet

4 participants