Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2082)

Unified Diff: cc/render_surface_filters.cc

Issue 12614011: cc: Chromify RenderSurfaceFilters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: .f Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/render_surface_filters.h ('k') | cc/render_surface_filters_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/render_surface_filters.cc
diff --git a/cc/render_surface_filters.cc b/cc/render_surface_filters.cc
index f04fbb984776414dc9f176dd48ad4f449e9e71af..19159e7fbe9f1f7353d6061c4a2ff72595188640 100644
--- a/cc/render_surface_filters.cc
+++ b/cc/render_surface_filters.cc
@@ -20,147 +20,137 @@ namespace cc {
namespace {
-void getBrightnessMatrix(float amount, SkScalar matrix[20])
-{
- // Spec implementation
- // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
- // <feFunc[R|G|B] type="linear" slope="[amount]">
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = amount;
- matrix[18] = 1;
+void GetBrightnessMatrix(float amount, SkScalar matrix[20]) {
+ // Spec implementation
+ // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
+ // <feFunc[R|G|B] type="linear" slope="[amount]">
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = amount;
+ matrix[18] = 1.f;
}
-void getSaturatingBrightnessMatrix(float amount, SkScalar matrix[20])
-{
- // Legacy implementation used by internal clients.
- // <feFunc[R|G|B] type="linear" intercept="[amount]"/>
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1;
- matrix[4] = matrix[9] = matrix[14] = amount * 255;
+void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) {
+ // Legacy implementation used by internal clients.
+ // <feFunc[R|G|B] type="linear" intercept="[amount]"/>
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
+ matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
}
-void getContrastMatrix(float amount, SkScalar matrix[20])
-{
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = amount;
- matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255;
- matrix[18] = 1;
+void GetContrastMatrix(float amount, SkScalar matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = amount;
+ matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f;
+ matrix[18] = 1.f;
}
-void getSaturateMatrix(float amount, SkScalar matrix[20])
-{
- // Note, these values are computed to ensure matrixNeedsClamping is false
- // for amount in [0..1]
- matrix[0] = 0.213f + 0.787f * amount;
- matrix[1] = 0.715f - 0.715f * amount;
- matrix[2] = 1.f - (matrix[0] + matrix[1]);
- matrix[3] = matrix[4] = 0;
- matrix[5] = 0.213f - 0.213f * amount;
- matrix[6] = 0.715f + 0.285f * amount;
- matrix[7] = 1.f - (matrix[5] + matrix[6]);
- matrix[8] = matrix[9] = 0;
- matrix[10] = 0.213f - 0.213f * amount;
- matrix[11] = 0.715f - 0.715f * amount;
- matrix[12] = 1.f - (matrix[10] + matrix[11]);
- matrix[13] = matrix[14] = 0;
- matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
- matrix[18] = 1;
+void GetSaturateMatrix(float amount, SkScalar matrix[20]) {
+ // Note, these values are computed to ensure matrixNeedsClamping is false
+ // for amount in [0..1]
+ matrix[0] = 0.213f + 0.787f * amount;
+ matrix[1] = 0.715f - 0.715f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0.f;
+ matrix[5] = 0.213f - 0.213f * amount;
+ matrix[6] = 0.715f + 0.285f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0.f;
+ matrix[10] = 0.213f - 0.213f * amount;
+ matrix[11] = 0.715f - 0.715f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0.f;
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
+ matrix[18] = 1.f;
}
-void getHueRotateMatrix(float hue, SkScalar matrix[20])
-{
- const float kPi = 3.1415926535897932384626433832795f;
-
- float cosHue = cosf(hue * kPi / 180);
- float sinHue = sinf(hue * kPi / 180);
- matrix[0] = 0.213f + cosHue * 0.787f - sinHue * 0.213f;
- matrix[1] = 0.715f - cosHue * 0.715f - sinHue * 0.715f;
- matrix[2] = 0.072f - cosHue * 0.072f + sinHue * 0.928f;
- matrix[3] = matrix[4] = 0;
- matrix[5] = 0.213f - cosHue * 0.213f + sinHue * 0.143f;
- matrix[6] = 0.715f + cosHue * 0.285f + sinHue * 0.140f;
- matrix[7] = 0.072f - cosHue * 0.072f - sinHue * 0.283f;
- matrix[8] = matrix[9] = 0;
- matrix[10] = 0.213f - cosHue * 0.213f - sinHue * 0.787f;
- matrix[11] = 0.715f - cosHue * 0.715f + sinHue * 0.715f;
- matrix[12] = 0.072f + cosHue * 0.928f + sinHue * 0.072f;
- matrix[13] = matrix[14] = 0;
- matrix[15] = matrix[16] = matrix[17] = 0;
- matrix[18] = 1;
- matrix[19] = 0;
+void GetHueRotateMatrix(float hue, SkScalar matrix[20]) {
+ const float kPi = 3.1415926535897932384626433832795f;
+
+ float cos_hue = cosf(hue * kPi / 180.f);
+ float sin_hue = sinf(hue * kPi / 180.f);
+ matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f;
+ matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f;
+ matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f;
+ matrix[3] = matrix[4] = 0.f;
+ matrix[5] = 0.213f - cos_hue * 0.213f + sin_hue * 0.143f;
+ matrix[6] = 0.715f + cos_hue * 0.285f + sin_hue * 0.140f;
+ matrix[7] = 0.072f - cos_hue * 0.072f - sin_hue * 0.283f;
+ matrix[8] = matrix[9] = 0.f;
+ matrix[10] = 0.213f - cos_hue * 0.213f - sin_hue * 0.787f;
+ matrix[11] = 0.715f - cos_hue * 0.715f + sin_hue * 0.715f;
+ matrix[12] = 0.072f + cos_hue * 0.928f + sin_hue * 0.072f;
+ matrix[13] = matrix[14] = 0.f;
+ matrix[15] = matrix[16] = matrix[17] = 0.f;
+ matrix[18] = 1.f;
+ matrix[19] = 0.f;
}
-void getInvertMatrix(float amount, SkScalar matrix[20])
-{
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = 1 - 2 * amount;
- matrix[4] = matrix[9] = matrix[14] = amount * 255;
- matrix[18] = 1;
+void GetInvertMatrix(float amount, SkScalar matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount;
+ matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
+ matrix[18] = 1.f;
}
-void getOpacityMatrix(float amount, SkScalar matrix[20])
-{
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = 1;
- matrix[18] = amount;
+void GetOpacityMatrix(float amount, SkScalar matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = 1.f;
+ matrix[18] = amount;
}
-void getGrayscaleMatrix(float amount, SkScalar matrix[20])
-{
- // Note, these values are computed to ensure matrixNeedsClamping is false
- // for amount in [0..1]
- matrix[0] = 0.2126f + 0.7874f * amount;
- matrix[1] = 0.7152f - 0.7152f * amount;
- matrix[2] = 1.f - (matrix[0] + matrix[1]);
- matrix[3] = matrix[4] = 0;
-
- matrix[5] = 0.2126f - 0.2126f * amount;
- matrix[6] = 0.7152f + 0.2848f * amount;
- matrix[7] = 1.f - (matrix[5] + matrix[6]);
- matrix[8] = matrix[9] = 0;
-
- matrix[10] = 0.2126f - 0.2126f * amount;
- matrix[11] = 0.7152f - 0.7152f * amount;
- matrix[12] = 1.f - (matrix[10] + matrix[11]);
- matrix[13] = matrix[14] = 0;
-
- matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
- matrix[18] = 1;
+void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) {
+ // Note, these values are computed to ensure matrixNeedsClamping is false
+ // for amount in [0..1]
+ matrix[0] = 0.2126f + 0.7874f * amount;
+ matrix[1] = 0.7152f - 0.7152f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0.f;
+
+ matrix[5] = 0.2126f - 0.2126f * amount;
+ matrix[6] = 0.7152f + 0.2848f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0.f;
+
+ matrix[10] = 0.2126f - 0.2126f * amount;
+ matrix[11] = 0.7152f - 0.7152f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0.f;
+
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
+ matrix[18] = 1.f;
}
-void getSepiaMatrix(float amount, SkScalar matrix[20])
-{
- matrix[0] = 0.393f + 0.607f * amount;
- matrix[1] = 0.769f - 0.769f * amount;
- matrix[2] = 0.189f - 0.189f * amount;
- matrix[3] = matrix[4] = 0;
-
- matrix[5] = 0.349f - 0.349f * amount;
- matrix[6] = 0.686f + 0.314f * amount;
- matrix[7] = 0.168f - 0.168f * amount;
- matrix[8] = matrix[9] = 0;
-
- matrix[10] = 0.272f - 0.272f * amount;
- matrix[11] = 0.534f - 0.534f * amount;
- matrix[12] = 0.131f + 0.869f * amount;
- matrix[13] = matrix[14] = 0;
-
- matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
- matrix[18] = 1;
+void GetSepiaMatrix(float amount, SkScalar matrix[20]) {
+ matrix[0] = 0.393f + 0.607f * amount;
+ matrix[1] = 0.769f - 0.769f * amount;
+ matrix[2] = 0.189f - 0.189f * amount;
+ matrix[3] = matrix[4] = 0.f;
+
+ matrix[5] = 0.349f - 0.349f * amount;
+ matrix[6] = 0.686f + 0.314f * amount;
+ matrix[7] = 0.168f - 0.168f * amount;
+ matrix[8] = matrix[9] = 0.f;
+
+ matrix[10] = 0.272f - 0.272f * amount;
+ matrix[11] = 0.534f - 0.534f * amount;
+ matrix[12] = 0.131f + 0.869f * amount;
+ matrix[13] = matrix[14] = 0.f;
+
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
+ matrix[18] = 1.f;
}
// The 5x4 matrix is really a "compressed" version of a 5x5 matrix that'd have
// (0 0 0 0 1) as a last row, and that would be applied to a 5-vector extended
// from the 4-vector color with a 1.
-void multColorMatrix(SkScalar a[20], SkScalar b[20], SkScalar out[20])
-{
- for (int j = 0; j < 4; ++j) {
- for (int i = 0; i < 5; ++i) {
- out[i+j*5] = i == 4 ? a[4+j*5] : 0;
- for (int k = 0; k < 4; ++k)
- out[i+j*5] += a[k+j*5] * b[i+k*5];
- }
+void MultColorMatrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) {
+ for (int j = 0; j < 4; ++j) {
+ for (int i = 0; i < 5; ++i) {
+ out[i+j*5] = i == 4 ? a[4+j*5] : 0.f;
+ for (int k = 0; k < 4; ++k)
+ out[i+j*5] += a[k+j*5] * b[i+k*5];
}
+ }
}
// To detect if we need to apply clamping after applying a matrix, we check if
@@ -173,280 +163,296 @@ void multColorMatrix(SkScalar a[20], SkScalar b[20], SkScalar out[20])
// Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
// minimum value will be for R=0 if x>0 or R=255 if x<0.
// Same goes for all components.
-bool componentNeedsClamping(SkScalar row[5])
-{
- SkScalar maxValue = row[4] / 255;
- SkScalar minValue = row[4] / 255;
- for (int i = 0; i < 4; ++i) {
- if (row[i] > 0)
- maxValue += row[i];
- else
- minValue += row[i];
- }
- return (maxValue > 1) || (minValue < 0);
+bool ComponentNeedsClamping(SkScalar row[5]) {
+ SkScalar max_value = row[4] / 255.f;
+ SkScalar min_value = row[4] / 255.f;
+ for (int i = 0; i < 4; ++i) {
+ if (row[i] > 0)
+ max_value += row[i];
+ else
+ min_value += row[i];
+ }
+ return (max_value > 1.f) || (min_value < 0.f);
}
-bool matrixNeedsClamping(SkScalar matrix[20])
-{
- return componentNeedsClamping(matrix)
- || componentNeedsClamping(matrix+5)
- || componentNeedsClamping(matrix+10)
- || componentNeedsClamping(matrix+15);
+bool MatrixNeedsClamping(SkScalar matrix[20]) {
+ return ComponentNeedsClamping(matrix)
+ || ComponentNeedsClamping(matrix+5)
+ || ComponentNeedsClamping(matrix+10)
+ || ComponentNeedsClamping(matrix+15);
}
-bool getColorMatrix(const WebKit::WebFilterOperation& op, SkScalar matrix[20])
-{
- switch (op.type()) {
+bool GetColorMatrix(const WebKit::WebFilterOperation& op, SkScalar matrix[20]) {
+ switch (op.type()) {
case WebKit::WebFilterOperation::FilterTypeBrightness: {
- getBrightnessMatrix(op.amount(), matrix);
- return true;
+ GetBrightnessMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: {
- getSaturatingBrightnessMatrix(op.amount(), matrix);
- return true;
+ GetSaturatingBrightnessMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeContrast: {
- getContrastMatrix(op.amount(), matrix);
- return true;
+ GetContrastMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeGrayscale: {
- getGrayscaleMatrix(1 - op.amount(), matrix);
- return true;
+ GetGrayscaleMatrix(1.f - op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeSepia: {
- getSepiaMatrix(1 - op.amount(), matrix);
- return true;
+ GetSepiaMatrix(1.f - op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeSaturate: {
- getSaturateMatrix(op.amount(), matrix);
- return true;
+ GetSaturateMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeHueRotate: {
- getHueRotateMatrix(op.amount(), matrix);
- return true;
+ GetHueRotateMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeInvert: {
- getInvertMatrix(op.amount(), matrix);
- return true;
+ GetInvertMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeOpacity: {
- getOpacityMatrix(op.amount(), matrix);
- return true;
+ GetOpacityMatrix(op.amount(), matrix);
+ return true;
}
case WebKit::WebFilterOperation::FilterTypeColorMatrix: {
- memcpy(matrix, op.matrix(), sizeof(SkScalar[20]));
- return true;
+ memcpy(matrix, op.matrix(), sizeof(SkScalar[20]));
+ return true;
}
default:
- return false;
- }
+ return false;
+ }
}
class FilterBufferState {
-public:
- FilterBufferState(GrContext* grContext, const gfx::SizeF& size, unsigned textureId)
- : m_grContext(grContext)
- , m_currentTexture(0)
- {
- // Wrap the source texture in a Ganesh platform texture.
- GrBackendTextureDesc backendTextureDescription;
- backendTextureDescription.fWidth = size.width();
- backendTextureDescription.fHeight = size.height();
- backendTextureDescription.fConfig = kSkia8888_GrPixelConfig;
- backendTextureDescription.fTextureHandle = textureId;
- skia::RefPtr<GrTexture> texture = skia::AdoptRef(grContext->wrapBackendTexture(backendTextureDescription));
- // Place the platform texture inside an SkBitmap.
- m_source.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
- skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(texture.get()));
- m_source.setPixelRef(pixelRef.get());
+ public:
+ FilterBufferState(GrContext* gr_context,
+ gfx::SizeF size,
+ unsigned texture_id)
+ : gr_context_(gr_context),
+ current_texture_(0) {
+ // Wrap the source texture in a Ganesh platform texture.
+ GrBackendTextureDesc backend_texture_description;
+ backend_texture_description.fWidth = size.width();
+ backend_texture_description.fHeight = size.height();
+ backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
+ backend_texture_description.fTextureHandle = texture_id;
+ skia::RefPtr<GrTexture> texture = skia::AdoptRef(
+ gr_context->wrapBackendTexture(backend_texture_description));
+ // Place the platform texture inside an SkBitmap.
+ source_.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
+ skia::RefPtr<SkGrPixelRef> pixel_ref =
+ skia::AdoptRef(new SkGrPixelRef(texture.get()));
+ source_.setPixelRef(pixel_ref.get());
+ }
+
+ ~FilterBufferState() {}
+
+ bool Init(int filter_count) {
+ int scratch_count = std::min(2, filter_count);
+ GrTextureDesc desc;
+ desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
+ desc.fSampleCnt = 0;
+ desc.fWidth = source_.width();
+ desc.fHeight = source_.height();
+ desc.fConfig = kSkia8888_GrPixelConfig;
+ for (int i = 0; i < scratch_count; ++i) {
+ GrAutoScratchTexture scratch_texture(
+ gr_context_, desc, GrContext::kExact_ScratchTexMatch);
+ scratch_textures_[i] = skia::AdoptRef(scratch_texture.detach());
+ if (!scratch_textures_[i])
+ return false;
}
+ return true;
+ }
+
+ SkCanvas* Canvas() {
+ if (!canvas_.get())
+ CreateCanvas();
+ return canvas_.get();
+ }
+
+ const SkBitmap& Source() { return source_; }
+
+ void Swap() {
+ canvas_->flush();
+ canvas_.clear();
+ device_.clear();
+
+ skia::RefPtr<SkGrPixelRef> pixel_ref = skia::AdoptRef(
+ new SkGrPixelRef(scratch_textures_[current_texture_].get()));
+ source_.setPixelRef(pixel_ref.get());
+ current_texture_ = 1 - current_texture_;
+ }
+
+ private:
+ void CreateCanvas() {
+ DCHECK(scratch_textures_[current_texture_].get());
+ device_ = skia::AdoptRef(new SkGpuDevice(
+ gr_context_, scratch_textures_[current_texture_].get()));
+ canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
+ canvas_->clear(0x0);
+ }
+
+ GrContext* gr_context_;
+ SkBitmap source_;
+ skia::RefPtr<GrTexture> scratch_textures_[2];
+ int current_texture_;
+ skia::RefPtr<SkGpuDevice> device_;
+ skia::RefPtr<SkCanvas> canvas_;
+};
- ~FilterBufferState() { }
-
- bool init(int filterCount)
- {
- int scratchCount = std::min(2, filterCount);
- GrTextureDesc desc;
- desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
- desc.fSampleCnt = 0;
- desc.fWidth = m_source.width();
- desc.fHeight = m_source.height();
- desc.fConfig = kSkia8888_GrPixelConfig;
- for (int i = 0; i < scratchCount; ++i) {
- GrAutoScratchTexture scratchTexture(m_grContext, desc, GrContext::kExact_ScratchTexMatch);
- m_scratchTextures[i] = skia::AdoptRef(scratchTexture.detach());
- if (!m_scratchTextures[i])
- return false;
- }
- return true;
- }
+} // namespace
- SkCanvas* canvas()
- {
- if (!m_canvas.get())
- createCanvas();
- return m_canvas.get();
+WebKit::WebFilterOperations RenderSurfaceFilters::Optimize(
+ const WebKit::WebFilterOperations& filters) {
+ WebKit::WebFilterOperations new_list;
+
+ SkScalar accumulated_color_matrix[20];
+ bool have_accumulated_color_matrix = false;
+ for (unsigned i = 0; i < filters.size(); ++i) {
+ const WebKit::WebFilterOperation& op = filters.at(i);
+
+ // If the filter is a color matrix, we may be able to combine it with
+ // following filter(s) that also are color matrices.
+ SkScalar matrix[20];
+ if (GetColorMatrix(op, matrix)) {
+ if (have_accumulated_color_matrix) {
+ SkScalar newMatrix[20];
+ MultColorMatrix(matrix, accumulated_color_matrix, newMatrix);
+ memcpy(accumulated_color_matrix,
+ newMatrix,
+ sizeof(accumulated_color_matrix));
+ } else {
+ memcpy(accumulated_color_matrix,
+ matrix,
+ sizeof(accumulated_color_matrix));
+ have_accumulated_color_matrix = true;
+ }
+
+ // We can only combine matrices if clamping of color components
+ // would have no effect.
+ if (!MatrixNeedsClamping(accumulated_color_matrix))
+ continue;
}
- const SkBitmap& source() { return m_source; }
-
- void swap()
- {
- m_canvas->flush();
- m_canvas.clear();
- m_device.clear();
-
- skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(m_scratchTextures[m_currentTexture].get()));
- m_source.setPixelRef(pixelRef.get());
- m_currentTexture = 1 - m_currentTexture;
+ if (have_accumulated_color_matrix) {
+ new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter(
+ accumulated_color_matrix));
}
+ have_accumulated_color_matrix = false;
-private:
- void createCanvas()
- {
- DCHECK(m_scratchTextures[m_currentTexture].get());
- m_device = skia::AdoptRef(new SkGpuDevice(m_grContext, m_scratchTextures[m_currentTexture].get()));
- m_canvas = skia::AdoptRef(new SkCanvas(m_device.get()));
- m_canvas->clear(0x0);
+ switch (op.type()) {
+ case WebKit::WebFilterOperation::FilterTypeBlur:
+ case WebKit::WebFilterOperation::FilterTypeDropShadow:
+ case WebKit::WebFilterOperation::FilterTypeZoom:
+ new_list.append(op);
+ break;
+ case WebKit::WebFilterOperation::FilterTypeBrightness:
+ case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness:
+ case WebKit::WebFilterOperation::FilterTypeContrast:
+ case WebKit::WebFilterOperation::FilterTypeGrayscale:
+ case WebKit::WebFilterOperation::FilterTypeSepia:
+ case WebKit::WebFilterOperation::FilterTypeSaturate:
+ case WebKit::WebFilterOperation::FilterTypeHueRotate:
+ case WebKit::WebFilterOperation::FilterTypeInvert:
+ case WebKit::WebFilterOperation::FilterTypeOpacity:
+ case WebKit::WebFilterOperation::FilterTypeColorMatrix:
+ break;
}
+ }
+ if (have_accumulated_color_matrix) {
+ new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter(
+ accumulated_color_matrix));
+ }
+ return new_list;
+}
- GrContext* m_grContext;
- SkBitmap m_source;
- skia::RefPtr<GrTexture> m_scratchTextures[2];
- int m_currentTexture;
- skia::RefPtr<SkGpuDevice> m_device;
- skia::RefPtr<SkCanvas> m_canvas;
-};
-
-} // namespace
+SkBitmap RenderSurfaceFilters::Apply(const WebKit::WebFilterOperations& filters,
+ unsigned texture_id,
+ gfx::SizeF size,
+ GrContext* gr_context) {
+ DCHECK(gr_context);
-WebKit::WebFilterOperations RenderSurfaceFilters::optimize(const WebKit::WebFilterOperations& filters)
-{
- WebKit::WebFilterOperations newList;
-
- SkScalar accumulatedColorMatrix[20];
- bool haveAccumulatedColorMatrix = false;
- for (unsigned i = 0; i < filters.size(); ++i) {
- const WebKit::WebFilterOperation& op = filters.at(i);
-
- // If the filter is a color matrix, we may be able to combine it with
- // following filter(s) that also are color matrices.
- SkScalar matrix[20];
- if (getColorMatrix(op, matrix)) {
- if (haveAccumulatedColorMatrix) {
- SkScalar newMatrix[20];
- multColorMatrix(matrix, accumulatedColorMatrix, newMatrix);
- memcpy(accumulatedColorMatrix, newMatrix, sizeof(accumulatedColorMatrix));
- } else {
- memcpy(accumulatedColorMatrix, matrix, sizeof(accumulatedColorMatrix));
- haveAccumulatedColorMatrix = true;
- }
-
- // We can only combine matrices if clamping of color components
- // would have no effect.
- if (!matrixNeedsClamping(accumulatedColorMatrix))
- continue;
- }
-
- if (haveAccumulatedColorMatrix)
- newList.append(WebKit::WebFilterOperation::createColorMatrixFilter(accumulatedColorMatrix));
- haveAccumulatedColorMatrix = false;
-
- switch (op.type()) {
- case WebKit::WebFilterOperation::FilterTypeBlur:
- case WebKit::WebFilterOperation::FilterTypeDropShadow:
- case WebKit::WebFilterOperation::FilterTypeZoom:
- newList.append(op);
- break;
- case WebKit::WebFilterOperation::FilterTypeBrightness:
- case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness:
- case WebKit::WebFilterOperation::FilterTypeContrast:
- case WebKit::WebFilterOperation::FilterTypeGrayscale:
- case WebKit::WebFilterOperation::FilterTypeSepia:
- case WebKit::WebFilterOperation::FilterTypeSaturate:
- case WebKit::WebFilterOperation::FilterTypeHueRotate:
- case WebKit::WebFilterOperation::FilterTypeInvert:
- case WebKit::WebFilterOperation::FilterTypeOpacity:
- case WebKit::WebFilterOperation::FilterTypeColorMatrix:
- break;
- }
- }
- if (haveAccumulatedColorMatrix)
- newList.append(WebKit::WebFilterOperation::createColorMatrixFilter(accumulatedColorMatrix));
- return newList;
-}
+ WebKit::WebFilterOperations optimized_filters = Optimize(filters);
+ FilterBufferState state(gr_context, size, texture_id);
+ if (!state.Init(optimized_filters.size()))
+ return SkBitmap();
-SkBitmap RenderSurfaceFilters::apply(const WebKit::WebFilterOperations& filters, unsigned textureId, gfx::SizeF size, GrContext* grContext)
-{
- DCHECK(grContext);
-
- WebKit::WebFilterOperations optimizedFilters = optimize(filters);
- FilterBufferState state(grContext, size, textureId);
- if (!state.init(optimizedFilters.size()))
- return SkBitmap();
-
- for (unsigned i = 0; i < optimizedFilters.size(); ++i) {
- const WebKit::WebFilterOperation& op = optimizedFilters.at(i);
- SkCanvas* canvas = state.canvas();
- switch (op.type()) {
- case WebKit::WebFilterOperation::FilterTypeColorMatrix: {
- SkPaint paint;
- skia::RefPtr<SkColorMatrixFilter> filter = skia::AdoptRef(new SkColorMatrixFilter(op.matrix()));
- paint.setColorFilter(filter.get());
- canvas->drawBitmap(state.source(), 0, 0, &paint);
- break;
- }
- case WebKit::WebFilterOperation::FilterTypeBlur: {
- float stdDeviation = op.amount();
- skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(new SkBlurImageFilter(stdDeviation, stdDeviation));
- SkPaint paint;
- paint.setImageFilter(filter.get());
- canvas->drawSprite(state.source(), 0, 0, &paint);
- break;
- }
- case WebKit::WebFilterOperation::FilterTypeDropShadow: {
- skia::RefPtr<SkImageFilter> blurFilter = skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount()));
- skia::RefPtr<SkColorFilter> colorFilter = skia::AdoptRef(SkColorFilter::CreateModeFilter(op.dropShadowColor(), SkXfermode::kSrcIn_Mode));
- SkPaint paint;
- paint.setImageFilter(blurFilter.get());
- paint.setColorFilter(colorFilter.get());
- paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- canvas->saveLayer(0, &paint);
- canvas->drawBitmap(state.source(), op.dropShadowOffset().x, -op.dropShadowOffset().y);
- canvas->restore();
- canvas->drawBitmap(state.source(), 0, 0);
- break;
- }
- case WebKit::WebFilterOperation::FilterTypeZoom: {
- SkPaint paint;
- skia::RefPtr<SkImageFilter> zoomFilter = skia::AdoptRef(
- new SkMagnifierImageFilter(
- SkRect::MakeXYWH(op.zoomRect().x,
- op.zoomRect().y,
- op.zoomRect().width,
- op.zoomRect().height),
- op.amount()));
- paint.setImageFilter(zoomFilter.get());
- canvas->saveLayer(0, &paint);
- canvas->drawBitmap(state.source(), 0, 0);
- canvas->restore();
- break;
- }
- case WebKit::WebFilterOperation::FilterTypeBrightness:
- case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness:
- case WebKit::WebFilterOperation::FilterTypeContrast:
- case WebKit::WebFilterOperation::FilterTypeGrayscale:
- case WebKit::WebFilterOperation::FilterTypeSepia:
- case WebKit::WebFilterOperation::FilterTypeSaturate:
- case WebKit::WebFilterOperation::FilterTypeHueRotate:
- case WebKit::WebFilterOperation::FilterTypeInvert:
- case WebKit::WebFilterOperation::FilterTypeOpacity:
- NOTREACHED();
- break;
- }
- state.swap();
+ for (unsigned i = 0; i < optimized_filters.size(); ++i) {
+ const WebKit::WebFilterOperation& op = optimized_filters.at(i);
+ SkCanvas* canvas = state.Canvas();
+ switch (op.type()) {
+ case WebKit::WebFilterOperation::FilterTypeColorMatrix: {
+ SkPaint paint;
+ skia::RefPtr<SkColorMatrixFilter> filter =
+ skia::AdoptRef(new SkColorMatrixFilter(op.matrix()));
+ paint.setColorFilter(filter.get());
+ canvas->drawBitmap(state.Source(), 0, 0, &paint);
+ break;
+ }
+ case WebKit::WebFilterOperation::FilterTypeBlur: {
+ float std_deviation = op.amount();
+ skia::RefPtr<SkImageFilter> filter =
+ skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation));
+ SkPaint paint;
+ paint.setImageFilter(filter.get());
+ canvas->drawSprite(state.Source(), 0, 0, &paint);
+ break;
+ }
+ case WebKit::WebFilterOperation::FilterTypeDropShadow: {
+ skia::RefPtr<SkImageFilter> blur_filter =
+ skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount()));
+ skia::RefPtr<SkColorFilter> color_filter =
+ skia::AdoptRef(SkColorFilter::CreateModeFilter(
+ op.dropShadowColor(), SkXfermode::kSrcIn_Mode));
+ SkPaint paint;
+ paint.setImageFilter(blur_filter.get());
+ paint.setColorFilter(color_filter.get());
+ paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+ canvas->saveLayer(NULL, &paint);
+ canvas->drawBitmap(state.Source(),
+ op.dropShadowOffset().x,
+ -op.dropShadowOffset().y);
+ canvas->restore();
+ canvas->drawBitmap(state.Source(), 0, 0);
+ break;
+ }
+ case WebKit::WebFilterOperation::FilterTypeZoom: {
+ SkPaint paint;
+ skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef(
+ new SkMagnifierImageFilter(
+ SkRect::MakeXYWH(op.zoomRect().x,
+ op.zoomRect().y,
+ op.zoomRect().width,
+ op.zoomRect().height),
+ op.amount()));
+ paint.setImageFilter(zoom_filter.get());
+ canvas->saveLayer(NULL, &paint);
+ canvas->drawBitmap(state.Source(), 0, 0);
+ canvas->restore();
+ break;
+ }
+ case WebKit::WebFilterOperation::FilterTypeBrightness:
+ case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness:
+ case WebKit::WebFilterOperation::FilterTypeContrast:
+ case WebKit::WebFilterOperation::FilterTypeGrayscale:
+ case WebKit::WebFilterOperation::FilterTypeSepia:
+ case WebKit::WebFilterOperation::FilterTypeSaturate:
+ case WebKit::WebFilterOperation::FilterTypeHueRotate:
+ case WebKit::WebFilterOperation::FilterTypeInvert:
+ case WebKit::WebFilterOperation::FilterTypeOpacity:
+ NOTREACHED();
+ break;
}
- return state.source();
+ state.Swap();
+ }
+ return state.Source();
}
} // namespace cc
« no previous file with comments | « cc/render_surface_filters.h ('k') | cc/render_surface_filters_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698