Chromium Code Reviews| Index: skia/ext/convolver.cc |
| =================================================================== |
| --- skia/ext/convolver.cc (revision 71667) |
| +++ skia/ext/convolver.cc (working copy) |
| @@ -1,4 +1,4 @@ |
| -// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -233,32 +233,56 @@ |
| void ConvolutionFilter1D::AddFilter(int filter_offset, |
| const float* filter_values, |
| int filter_length) { |
| - FilterInstance instance; |
| - instance.data_location = static_cast<int>(filter_values_.size()); |
| - instance.offset = filter_offset; |
| - instance.length = filter_length; |
| - filters_.push_back(instance); |
| - |
| SkASSERT(filter_length > 0); |
| - for (int i = 0; i < filter_length; i++) |
| - filter_values_.push_back(FloatToFixed(filter_values[i])); |
| - max_filter_ = std::max(max_filter_, filter_length); |
| + std::vector<Fixed> fixed_values; |
| + fixed_values.reserve(filter_length); |
| + |
| + for (int i = 0; i < filter_length; ++i) |
| + fixed_values.push_back(FloatToFixed(filter_values[i])); |
| + |
| + AddFilter(filter_offset, &fixed_values[0], filter_length); |
| } |
| void ConvolutionFilter1D::AddFilter(int filter_offset, |
| const Fixed* filter_values, |
| int filter_length) { |
| + // It is common for leading/trailing filter values to be zeros. In such |
| + // cases it is beneficial to only store the central factors. |
| + // For a scaling to 1/4th in each dimension using a Lanczos-2 filter on |
| + // a 1080p image this optimization gives a ~10% speed improvement. |
| + int first_non_zero = 0; |
| + while (first_non_zero < filter_length && filter_values[first_non_zero] == 0) { |
|
brettw
2011/01/20 21:48:06
Be consistent about usage for {} for single-line c
evannier
2011/01/24 21:09:58
Done.
|
| + first_non_zero++; |
| + } |
| + |
| + if (first_non_zero < filter_length) { |
| + // Here we have at least one non-zero factor. |
| + int last_non_zero = filter_length - 1; |
| + while (last_non_zero >= 0 && filter_values[last_non_zero] == 0) { |
| + last_non_zero--; |
| + } |
| + |
| + filter_offset += first_non_zero; |
| + filter_length = last_non_zero + 1 - first_non_zero; |
| + SkASSERT(filter_length > 0); |
| + |
| + for (int i = first_non_zero; i <= last_non_zero; i++) |
| + filter_values_.push_back(filter_values[i]); |
| + } else { |
| + // Here all the factors were zeroes. |
| + filter_length = 0; |
| + } |
| + |
| FilterInstance instance; |
| - instance.data_location = static_cast<int>(filter_values_.size()); |
| + |
| + // We pushed filter_length elements onto filter_values_ |
| + instance.data_location = (static_cast<int>(filter_values_.size()) - |
| + filter_length); |
| instance.offset = filter_offset; |
| instance.length = filter_length; |
| filters_.push_back(instance); |
| - SkASSERT(filter_length > 0); |
| - for (int i = 0; i < filter_length; i++) |
| - filter_values_.push_back(filter_values[i]); |
| - |
| max_filter_ = std::max(max_filter_, filter_length); |
| } |
| @@ -269,6 +293,7 @@ |
| bool source_has_alpha, |
| const ConvolutionFilter1D& filter_x, |
| const ConvolutionFilter1D& filter_y, |
| + int output_byte_row_stride, |
| unsigned char* output) { |
| int max_y_filter_size = filter_y.max_filter(); |
| @@ -292,7 +317,7 @@ |
| // Loop over every possible output row, processing just enough horizontal |
| // convolutions to run each subsequent vertical convolution. |
| - int output_row_byte_width = filter_x.num_values() * 4; |
| + SkASSERT(output_byte_row_stride >= filter_x.num_values() * 4); |
| int num_output_rows = filter_y.num_values(); |
| for (int out_y = 0; out_y < num_output_rows; out_y++) { |
| filter_values = filter_y.FilterForValue(out_y, |
| @@ -313,7 +338,7 @@ |
| } |
| // Compute where in the output image this row of final data will go. |
| - unsigned char* cur_output_row = &output[out_y * output_row_byte_width]; |
| + unsigned char* cur_output_row = &output[out_y * output_byte_row_stride]; |
| // Get the list of rows that the circular buffer has, in order. |
| int first_row_in_circular_buffer; |
| @@ -338,4 +363,3 @@ |
| } |
| } // namespace skia |
| - |