mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
layout: Implement filter
per CSS-FILTERS § 5.
`blur` and `drop-shadow` are not yet supported, because the `text-shadow` PR makes some fundamental changes to blur rendering that are needed first.
This commit is contained in:
parent
6b3c05cdd2
commit
15d60d7ea4
20 changed files with 499 additions and 62 deletions
|
@ -41,7 +41,7 @@ use std::fmt;
|
|||
use std::slice::Items;
|
||||
use std::sync::Arc;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{border_style, cursor, pointer_events};
|
||||
use style::computed_values::{border_style, cursor, filter, pointer_events};
|
||||
|
||||
// It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
|
||||
// layout to use.
|
||||
|
@ -163,8 +163,8 @@ pub struct StackingContext {
|
|||
pub overflow: Rect<Au>,
|
||||
/// The `z-index` for this stacking context.
|
||||
pub z_index: i32,
|
||||
/// The opacity of this stacking context.
|
||||
pub opacity: AzFloat,
|
||||
/// CSS filters to be applied to this stacking context (including opacity).
|
||||
pub filters: filter::T,
|
||||
}
|
||||
|
||||
impl StackingContext {
|
||||
|
@ -174,7 +174,7 @@ impl StackingContext {
|
|||
bounds: &Rect<Au>,
|
||||
overflow: &Rect<Au>,
|
||||
z_index: i32,
|
||||
opacity: AzFloat,
|
||||
filters: filter::T,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
-> StackingContext {
|
||||
StackingContext {
|
||||
|
@ -183,7 +183,7 @@ impl StackingContext {
|
|||
bounds: *bounds,
|
||||
overflow: *overflow,
|
||||
z_index: z_index,
|
||||
opacity: opacity,
|
||||
filters: filters,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl StackingContext {
|
|||
transform: &Matrix2D<AzFloat>,
|
||||
clip_rect: Option<&Rect<Au>>) {
|
||||
let temporary_draw_target =
|
||||
paint_context.get_or_create_temporary_draw_target(self.opacity);
|
||||
paint_context.get_or_create_temporary_draw_target(&self.filters);
|
||||
{
|
||||
let mut paint_subcontext = PaintContext {
|
||||
draw_target: temporary_draw_target.clone(),
|
||||
|
@ -306,7 +306,8 @@ impl StackingContext {
|
|||
paint_subcontext.draw_target.set_transform(&old_transform)
|
||||
}
|
||||
|
||||
paint_context.draw_temporary_draw_target_if_necessary(&temporary_draw_target, self.opacity)
|
||||
paint_context.draw_temporary_draw_target_if_necessary(&temporary_draw_target,
|
||||
&self.filters)
|
||||
}
|
||||
|
||||
/// Translate the given tile rect into the coordinate system of a child stacking context.
|
||||
|
|
198
components/gfx/filters.rs
Normal file
198
components/gfx/filters.rs
Normal file
|
@ -0,0 +1,198 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! CSS and SVG filter support.
|
||||
|
||||
use azure::AzFloat;
|
||||
use azure::azure_hl::{ColorMatrixAttribute, ColorMatrixInput, CompositeInput, DrawTarget};
|
||||
use azure::azure_hl::{FilterNode, FilterType, LinearTransferAttribute, LinearTransferInput};
|
||||
use azure::azure_hl::{Matrix5x4, TableTransferAttribute, TableTransferInput};
|
||||
|
||||
use std::num::FloatMath;
|
||||
use style::computed_values::filter;
|
||||
|
||||
/// Creates a filter pipeline from a set of CSS filters. Returns the destination end of the filter
|
||||
/// pipeline and the opacity.
|
||||
pub fn create_filters(draw_target: &DrawTarget,
|
||||
temporary_draw_target: &DrawTarget,
|
||||
style_filters: &filter::T)
|
||||
-> (FilterNode, AzFloat) {
|
||||
let mut opacity = 1.0;
|
||||
let mut filter = draw_target.create_filter(FilterType::Composite);
|
||||
filter.set_input(CompositeInput, &temporary_draw_target.snapshot());
|
||||
for style_filter in style_filters.filters.iter() {
|
||||
match *style_filter {
|
||||
filter::Filter::HueRotate(angle) => {
|
||||
let hue_rotate = draw_target.create_filter(FilterType::ColorMatrix);
|
||||
let matrix = self::hue_rotate(angle.radians() as AzFloat);
|
||||
hue_rotate.set_attribute(ColorMatrixAttribute::Matrix(matrix));
|
||||
hue_rotate.set_input(ColorMatrixInput, &filter);
|
||||
filter = hue_rotate
|
||||
}
|
||||
filter::Filter::Opacity(opacity_value) => opacity *= opacity_value as AzFloat,
|
||||
filter::Filter::Saturate(amount) => {
|
||||
let saturate = draw_target.create_filter(FilterType::ColorMatrix);
|
||||
let matrix = self::saturate(amount as AzFloat);
|
||||
saturate.set_attribute(ColorMatrixAttribute::Matrix(matrix));
|
||||
saturate.set_input(ColorMatrixInput, &filter);
|
||||
filter = saturate
|
||||
}
|
||||
filter::Filter::Sepia(amount) => {
|
||||
let sepia = draw_target.create_filter(FilterType::ColorMatrix);
|
||||
let matrix = self::sepia(amount as AzFloat);
|
||||
sepia.set_attribute(ColorMatrixAttribute::Matrix(matrix));
|
||||
sepia.set_input(ColorMatrixInput, &filter);
|
||||
filter = sepia
|
||||
}
|
||||
filter::Filter::Grayscale(amount) => {
|
||||
let amount = amount as AzFloat;
|
||||
let grayscale = draw_target.create_filter(FilterType::ColorMatrix);
|
||||
grayscale.set_attribute(ColorMatrixAttribute::Matrix(self::grayscale(amount)));
|
||||
grayscale.set_input(ColorMatrixInput, &filter);
|
||||
filter = grayscale
|
||||
}
|
||||
filter::Filter::Invert(amount) => {
|
||||
let amount = amount as AzFloat;
|
||||
let invert = draw_target.create_filter(FilterType::TableTransfer);
|
||||
invert.set_attribute(TableTransferAttribute::DisableR(false));
|
||||
invert.set_attribute(TableTransferAttribute::DisableG(false));
|
||||
invert.set_attribute(TableTransferAttribute::DisableB(false));
|
||||
invert.set_attribute(TableTransferAttribute::TableR(&[1.0, amount - 1.0]));
|
||||
invert.set_attribute(TableTransferAttribute::TableG(&[1.0, amount - 1.0]));
|
||||
invert.set_attribute(TableTransferAttribute::TableB(&[1.0, amount - 1.0]));
|
||||
invert.set_input(TableTransferInput, &filter);
|
||||
filter = invert
|
||||
}
|
||||
filter::Filter::Brightness(amount) => {
|
||||
let amount = amount as AzFloat;
|
||||
let brightness = draw_target.create_filter(FilterType::LinearTransfer);
|
||||
brightness.set_attribute(LinearTransferAttribute::DisableR(false));
|
||||
brightness.set_attribute(LinearTransferAttribute::DisableG(false));
|
||||
brightness.set_attribute(LinearTransferAttribute::DisableB(false));
|
||||
brightness.set_attribute(LinearTransferAttribute::SlopeR(amount));
|
||||
brightness.set_attribute(LinearTransferAttribute::SlopeG(amount));
|
||||
brightness.set_attribute(LinearTransferAttribute::SlopeB(amount));
|
||||
brightness.set_input(LinearTransferInput, &filter);
|
||||
filter = brightness
|
||||
}
|
||||
filter::Filter::Contrast(amount) => {
|
||||
let amount = amount as AzFloat;
|
||||
let contrast = draw_target.create_filter(FilterType::LinearTransfer);
|
||||
contrast.set_attribute(LinearTransferAttribute::DisableR(false));
|
||||
contrast.set_attribute(LinearTransferAttribute::DisableG(false));
|
||||
contrast.set_attribute(LinearTransferAttribute::DisableB(false));
|
||||
contrast.set_attribute(LinearTransferAttribute::SlopeR(amount));
|
||||
contrast.set_attribute(LinearTransferAttribute::SlopeG(amount));
|
||||
contrast.set_attribute(LinearTransferAttribute::SlopeB(amount));
|
||||
contrast.set_attribute(LinearTransferAttribute::InterceptR(-0.5 * amount + 0.5));
|
||||
contrast.set_attribute(LinearTransferAttribute::InterceptG(-0.5 * amount + 0.5));
|
||||
contrast.set_attribute(LinearTransferAttribute::InterceptB(-0.5 * amount + 0.5));
|
||||
contrast.set_input(LinearTransferInput, &filter);
|
||||
filter = contrast
|
||||
}
|
||||
}
|
||||
}
|
||||
(filter, opacity)
|
||||
}
|
||||
|
||||
/// Determines if we need a temporary draw target for the given set of filters.
|
||||
pub fn temporary_draw_target_needed_for_style_filters(filters: &filter::T) -> bool {
|
||||
for filter in filters.filters.iter() {
|
||||
match *filter {
|
||||
filter::Filter::Opacity(value) if value == 1.0 => continue,
|
||||
_ => return true,
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Creates a grayscale 5x4 color matrix per CSS-FILTERS § 12.1.1.
|
||||
fn grayscale(amount: AzFloat) -> Matrix5x4 {
|
||||
Matrix5x4 {
|
||||
m11: 0.2126 + 0.7874 * (1.0 - amount),
|
||||
m21: 0.7152 - 0.7152 * (1.0 - amount),
|
||||
m31: 0.0722 - 0.0722 * (1.0 - amount),
|
||||
m41: 0.0,
|
||||
m51: 0.0,
|
||||
m12: 0.2126 - 0.2126 * (1.0 - amount),
|
||||
m22: 0.7152 + 0.2848 * (1.0 - amount),
|
||||
m32: 0.0722 - 0.0722 * (1.0 - amount),
|
||||
m42: 0.0,
|
||||
m52: 0.0,
|
||||
m13: 0.2126 - 0.2126 * (1.0 - amount),
|
||||
m23: 0.7152 - 0.7152 * (1.0 - amount),
|
||||
m33: 0.0722 + 0.9278 * (1.0 - amount),
|
||||
m43: 0.0,
|
||||
m53: 0.0,
|
||||
m14: 0.0, m24: 0.0, m34: 0.0, m44: 1.0, m54: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a 5x4 hue rotation color matrix per CSS-FILTERS § 8.5.
|
||||
fn hue_rotate(angle: AzFloat) -> Matrix5x4 {
|
||||
let (c, s) = (angle.cos(), angle.sin());
|
||||
Matrix5x4 {
|
||||
m11: 0.213 + c * 0.787 + s * -0.213,
|
||||
m21: 0.715 + c * -0.715 + s * -0.715,
|
||||
m31: 0.072 + c * -0.072 + s * 0.928,
|
||||
m41: 0.0,
|
||||
m51: 0.0,
|
||||
m12: 0.213 + c * -0.213 + s * 0.143,
|
||||
m22: 0.715 + c * 0.285 + s * 0.140,
|
||||
m32: 0.072 + c * -0.072 + s * -0.283,
|
||||
m42: 0.0,
|
||||
m52: 0.0,
|
||||
m13: 0.213 + c * -0.213 + s * -0.787,
|
||||
m23: 0.715 + c * -0.715 + s * 0.715,
|
||||
m33: 0.072 + c * 0.928 + s * 0.072,
|
||||
m43: 0.0,
|
||||
m53: 0.0,
|
||||
m14: 0.0, m24: 0.0, m34: 0.0, m44: 1.0, m54: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a 5x4 saturation color matrix per CSS-FILTERS § 8.5.
|
||||
fn saturate(amount: AzFloat) -> Matrix5x4 {
|
||||
Matrix5x4 {
|
||||
m11: 0.213 + 0.787 * amount,
|
||||
m21: 0.715 - 0.715 * amount,
|
||||
m31: 0.072 - 0.072 * amount,
|
||||
m41: 0.0,
|
||||
m51: 0.0,
|
||||
m12: 0.213 - 0.213 * amount,
|
||||
m22: 0.715 + 0.285 * amount,
|
||||
m32: 0.072 - 0.072 * amount,
|
||||
m42: 0.0,
|
||||
m52: 0.0,
|
||||
m13: 0.213 - 0.213 * amount,
|
||||
m23: 0.715 - 0.715 * amount,
|
||||
m33: 0.072 + 0.928 * amount,
|
||||
m43: 0.0,
|
||||
m53: 0.0,
|
||||
m14: 0.0, m24: 0.0, m34: 0.0, m44: 1.0, m54: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a sepia 5x4 color matrix per CSS-FILTERS § 12.1.1.
|
||||
fn sepia(amount: AzFloat) -> Matrix5x4 {
|
||||
Matrix5x4 {
|
||||
m11: 0.393 + 0.607 * (1.0 - amount),
|
||||
m21: 0.769 - 0.769 * (1.0 - amount),
|
||||
m31: 0.189 - 0.189 * (1.0 - amount),
|
||||
m41: 0.0,
|
||||
m51: 0.0,
|
||||
m12: 0.349 - 0.349 * (1.0 - amount),
|
||||
m22: 0.686 + 0.314 * (1.0 - amount),
|
||||
m32: 0.168 - 0.168 * (1.0 - amount),
|
||||
m42: 0.0,
|
||||
m52: 0.0,
|
||||
m13: 0.272 - 0.272 * (1.0 - amount),
|
||||
m23: 0.534 - 0.534 * (1.0 - amount),
|
||||
m33: 0.131 + 0.869 * (1.0 - amount),
|
||||
m43: 0.0,
|
||||
m53: 0.0,
|
||||
m14: 0.0, m24: 0.0, m34: 0.0, m44: 1.0, m54: 0.0,
|
||||
}
|
||||
}
|
||||
|
|
@ -30,14 +30,14 @@ use azure::scaled_font::FontInfo;
|
|||
|
||||
#[cfg(any(target_os="linux", target_os = "android"))]
|
||||
fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFont {
|
||||
ScaledFont::new(BackendType::SkiaBackend, FontInfo::FontData(&template.bytes),
|
||||
ScaledFont::new(BackendType::Skia, FontInfo::FontData(&template.bytes),
|
||||
pt_size.to_subpx() as AzFloat)
|
||||
}
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFont {
|
||||
let cgfont = template.ctfont.as_ref().unwrap().copy_to_CGFont();
|
||||
ScaledFont::new(BackendType::SkiaBackend, &cgfont, pt_size.to_subpx() as AzFloat)
|
||||
ScaledFont::new(BackendType::Skia, &cgfont, pt_size.to_subpx() as AzFloat)
|
||||
}
|
||||
|
||||
static SMALL_CAPS_SCALE_FACTOR: f64 = 0.8; // Matches FireFox (see gfxFont.h)
|
||||
|
|
|
@ -68,6 +68,7 @@ pub mod font_template;
|
|||
|
||||
// Misc.
|
||||
mod buffer_map;
|
||||
mod filters;
|
||||
|
||||
// Platform-specific implementations.
|
||||
#[path="platform/mod.rs"]
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
//! Painting of display lists using Moz2D/Azure.
|
||||
|
||||
use azure::azure::AzIntSize;
|
||||
use azure::azure_hl::{SurfaceFormat, Color, ColorPattern, DrawOptions};
|
||||
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, ExtendMode, FilterType};
|
||||
use azure::azure_hl::{Color, ColorPattern};
|
||||
use azure::azure_hl::{DrawOptions, DrawSurfaceOptions, DrawTarget, ExtendMode, FilterType};
|
||||
use azure::azure_hl::{GaussianBlurInput, GradientStop, Filter, LinearGradientPattern};
|
||||
use azure::azure_hl::{PatternRef, Path, PathBuilder, CompositionOp};
|
||||
use azure::azure_hl::{GaussianBlurAttribute, StrokeOptions};
|
||||
use azure::azure_hl::{GaussianBlurAttribute, StrokeOptions, SurfaceFormat};
|
||||
use azure::scaled_font::ScaledFont;
|
||||
use azure::{AZ_CAP_BUTT, AzFloat, struct__AzDrawOptions, struct__AzGlyph};
|
||||
use azure::{struct__AzGlyphBuffer, struct__AzPoint, AzDrawTargetFillGlyphs};
|
||||
use display_list::TextOrientation::{SidewaysLeft, SidewaysRight, Upright};
|
||||
use display_list::{BOX_SHADOW_INFLATION_FACTOR, BorderRadii, ClippingRegion, TextDisplayItem};
|
||||
use filters;
|
||||
use font_context::FontContext;
|
||||
use geom::matrix2d::Matrix2D;
|
||||
use geom::point::Point2D;
|
||||
|
@ -33,7 +34,7 @@ use std::f32;
|
|||
use std::mem;
|
||||
use std::num::{Float, FloatMath};
|
||||
use std::ptr;
|
||||
use style::computed_values::border_style;
|
||||
use style::computed_values::{border_style, filter};
|
||||
use std::sync::Arc;
|
||||
use text::TextRun;
|
||||
use text::glyph::CharIndex;
|
||||
|
@ -75,7 +76,7 @@ impl<'a> PaintContext<'a> {
|
|||
pub fn draw_solid_color(&self, bounds: &Rect<Au>, color: Color) {
|
||||
self.draw_target.make_current();
|
||||
self.draw_target.fill_rect(&bounds.to_azure_rect(),
|
||||
PatternRef::ColorPatternRef(&ColorPattern::new(color)),
|
||||
PatternRef::Color(&ColorPattern::new(color)),
|
||||
None);
|
||||
}
|
||||
|
||||
|
@ -158,10 +159,9 @@ impl<'a> PaintContext<'a> {
|
|||
Size2D(self.screen_rect.size.width as AzFloat,
|
||||
self.screen_rect.size.height as AzFloat));
|
||||
let mut draw_options = DrawOptions::new(1.0, 0);
|
||||
draw_options.set_composition_op(CompositionOp::SourceOp);
|
||||
draw_options.set_composition_op(CompositionOp::Source);
|
||||
self.draw_target.make_current();
|
||||
self.draw_target.fill_rect(&rect, PatternRef::ColorPatternRef(&pattern),
|
||||
Some(&draw_options));
|
||||
self.draw_target.fill_rect(&rect, PatternRef::Color(&pattern), Some(&draw_options));
|
||||
}
|
||||
|
||||
fn draw_border_segment(&self,
|
||||
|
@ -859,19 +859,20 @@ impl<'a> PaintContext<'a> {
|
|||
stops: &[GradientStop]) {
|
||||
self.draw_target.make_current();
|
||||
|
||||
let stops = self.draw_target.create_gradient_stops(stops, ExtendMode::ExtendClamp);
|
||||
let stops = self.draw_target.create_gradient_stops(stops, ExtendMode::Clamp);
|
||||
let pattern = LinearGradientPattern::new(&start_point.to_azure_point(),
|
||||
&end_point.to_azure_point(),
|
||||
stops,
|
||||
&Matrix2D::identity());
|
||||
|
||||
self.draw_target.fill_rect(&bounds.to_azure_rect(),
|
||||
PatternRef::LinearGradientPatternRef(&pattern),
|
||||
PatternRef::LinearGradient(&pattern),
|
||||
None);
|
||||
}
|
||||
|
||||
pub fn get_or_create_temporary_draw_target(&mut self, opacity: AzFloat) -> DrawTarget {
|
||||
if opacity == 1.0 {
|
||||
pub fn get_or_create_temporary_draw_target(&mut self, filters: &filter::T) -> DrawTarget {
|
||||
// Determine if we need a temporary draw target.
|
||||
if !filters::temporary_draw_target_needed_for_style_filters(filters) {
|
||||
// Reuse the draw target, but remove the transient clip. If we don't do the latter,
|
||||
// we'll be in a state whereby the paint subcontext thinks it has no transient clip
|
||||
// (see `StackingContext::optimize_and_draw_into_context`) but it actually does,
|
||||
|
@ -883,10 +884,7 @@ impl<'a> PaintContext<'a> {
|
|||
|
||||
// FIXME(pcwalton): This surface might be bigger than necessary and waste memory.
|
||||
let size = self.draw_target.get_size();
|
||||
let size = Size2D {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
};
|
||||
let size = Size2D(size.width, size.height);
|
||||
|
||||
let temporary_draw_target =
|
||||
self.draw_target.create_similar_draw_target(&size, self.draw_target.get_format());
|
||||
|
@ -898,24 +896,29 @@ impl<'a> PaintContext<'a> {
|
|||
/// after doing all the painting, and the temporary draw target must not be used afterward.
|
||||
pub fn draw_temporary_draw_target_if_necessary(&mut self,
|
||||
temporary_draw_target: &DrawTarget,
|
||||
opacity: AzFloat) {
|
||||
filters: &filter::T) {
|
||||
if (*temporary_draw_target) == self.draw_target {
|
||||
// We're directly painting to the surface; nothing to do.
|
||||
return
|
||||
}
|
||||
|
||||
// Set up transforms.
|
||||
let old_transform = self.draw_target.get_transform();
|
||||
self.draw_target.set_transform(&Matrix2D::identity());
|
||||
temporary_draw_target.set_transform(&Matrix2D::identity());
|
||||
|
||||
// Create the Azure filter pipeline.
|
||||
let (filter_node, opacity) = filters::create_filters(&self.draw_target,
|
||||
temporary_draw_target,
|
||||
filters);
|
||||
|
||||
// Perform the blit operation.
|
||||
let rect = Rect(Point2D(0.0, 0.0), self.draw_target.get_size().to_azure_size());
|
||||
let source_surface = temporary_draw_target.snapshot();
|
||||
let draw_surface_options = DrawSurfaceOptions::new(Filter::Linear, true);
|
||||
let draw_options = DrawOptions::new(opacity, 0);
|
||||
self.draw_target.draw_surface(source_surface,
|
||||
rect,
|
||||
rect,
|
||||
draw_surface_options,
|
||||
draw_options);
|
||||
self.draw_target.draw_filter(&filter_node,
|
||||
&rect,
|
||||
&rect.origin,
|
||||
draw_options);
|
||||
self.draw_target.set_transform(&old_transform);
|
||||
}
|
||||
|
||||
|
@ -974,9 +977,9 @@ impl<'a> PaintContext<'a> {
|
|||
if blur_radius > Au(0) {
|
||||
// Go ahead and create the blur now. Despite the name, Azure's notion of `StdDeviation`
|
||||
// describes the blur radius, not the sigma for the Gaussian blur.
|
||||
let blur_filter = self.draw_target.create_filter(FilterType::GaussianBlurFilterType);
|
||||
blur_filter.set_attribute(GaussianBlurAttribute::StdDeviationGaussianBlurAttribute(
|
||||
blur_radius.to_subpx() as AzFloat));
|
||||
let blur_filter = self.draw_target.create_filter(FilterType::GaussianBlur);
|
||||
blur_filter.set_attribute(GaussianBlurAttribute::StdDeviation(blur_radius.to_subpx() as
|
||||
AzFloat));
|
||||
blur_filter.set_input(GaussianBlurInput, &temporary_draw_target.snapshot());
|
||||
|
||||
// Blit the blur onto the tile. We undo the transforms here because we want to directly
|
||||
|
@ -985,7 +988,7 @@ impl<'a> PaintContext<'a> {
|
|||
self.draw_target.set_transform(&Matrix2D::identity());
|
||||
let temporary_draw_target_size = temporary_draw_target.get_size();
|
||||
self.draw_target
|
||||
.draw_filter(blur_filter,
|
||||
.draw_filter(&blur_filter,
|
||||
&Rect(Point2D(0.0, 0.0),
|
||||
Size2D(temporary_draw_target_size.width as AzFloat,
|
||||
temporary_draw_target_size.height as AzFloat)),
|
||||
|
|
|
@ -524,11 +524,11 @@ impl WorkerThread {
|
|||
-> DrawTarget {
|
||||
let size = Size2D(tile.screen_rect.size.width as i32, tile.screen_rect.size.height as i32);
|
||||
let draw_target = if !opts::get().gpu_painting {
|
||||
DrawTarget::new(BackendType::SkiaBackend, size, SurfaceFormat::B8G8R8A8)
|
||||
DrawTarget::new(BackendType::Skia, size, SurfaceFormat::B8G8R8A8)
|
||||
} else {
|
||||
// FIXME(pcwalton): Cache the components of draw targets (texture color buffer,
|
||||
// paintbuffers) instead of recreating them.
|
||||
let draw_target = DrawTarget::new_with_fbo(BackendType::SkiaBackend,
|
||||
let draw_target = DrawTarget::new_with_fbo(BackendType::Skia,
|
||||
native_graphics_context!(self),
|
||||
size,
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue