author | Jeff Muizelaar <jmuizelaar@mozilla.com> |
Wed, 01 Mar 2017 09:10:53 -0500 | |
changeset 345876 | 7d88bb71fefb36157f16769e87658a39248a2a91 |
parent 345875 | e306b40ff823a65433b153cd0ab85f720ab05e02 |
child 345877 | 9059ef02d91ba49bb3cf3b9cdd4c92bc99a4d4b0 |
push id | 38337 |
push user | kwierso@gmail.com |
push date | Sat, 04 Mar 2017 01:30:14 +0000 |
treeherder | autoland@b691557cb7a3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nical |
bugs | 1342558 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -399,17 +399,25 @@ WebRenderBridgeParent::ProcessWebrenderC op.clip_mode()); break; } default: NS_RUNTIMEABORT("not reached"); } } builder.End(); - mApi->SetRootDisplayList(gfx::Color(0.3f, 0.f, 0.f, 1.f), aEpoch, LayerSize(aSize.width, aSize.height), builder); + WrBuiltDisplayListDescriptor dlDesc; + wr::VecU8 dlData; + WrAuxiliaryListsDescriptor auxDesc; + wr::VecU8 auxData; + builder.Finalize(dlDesc, dlData, auxDesc, auxData); + mApi->SetRootDisplayList(gfx::Color(0.3f, 0.f, 0.f, 1.f), aEpoch, LayerSize(aSize.width, aSize.height), + mPipelineId, + dlDesc, dlData.inner.data, dlData.inner.length, + auxDesc, auxData.inner.data, auxData.inner.length); ScheduleComposition(); DeleteOldImages(); // XXX remove it when external image key is used. if (!keysToDelete.empty()) { mKeysToDelete.swap(keysToDelete); }
--- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -159,21 +159,34 @@ WebRenderAPI::GenerateFrame() { wr_api_generate_frame(mWrApi); } void WebRenderAPI::SetRootDisplayList(gfx::Color aBgColor, Epoch aEpoch, LayerSize aViewportSize, - DisplayListBuilder& aBuilder) + WrPipelineId pipeline_id, + WrBuiltDisplayListDescriptor dl_descriptor, + uint8_t *dl_data, + size_t dl_size, + WrAuxiliaryListsDescriptor aux_descriptor, + uint8_t *aux_data, + size_t aux_size) { - wr_api_set_root_display_list(mWrApi, aBuilder.mWrState, - aEpoch, - aViewportSize.width, aViewportSize.height); + wr_api_set_root_display_list(mWrApi, + aEpoch, + aViewportSize.width, aViewportSize.height, + pipeline_id, + dl_descriptor, + dl_data, + dl_size, + aux_descriptor, + aux_data, + aux_size); } void WebRenderAPI::Readback(gfx::IntSize size, uint8_t *buffer, uint32_t buffer_size) { class Readback : public RendererEvent @@ -334,16 +347,29 @@ DisplayListBuilder::Begin(const LayerInt void DisplayListBuilder::End() { wr_dp_end(mWrState); } void +DisplayListBuilder::Finalize(WrBuiltDisplayListDescriptor& dl_descriptor, + wr::VecU8& dl_data, + WrAuxiliaryListsDescriptor& aux_descriptor, + wr::VecU8& aux_data) +{ + wr_api_finalize_builder(mWrState, + dl_descriptor, + dl_data.inner, + aux_descriptor, + aux_data.inner); +} + +void DisplayListBuilder::PushStackingContext(const WrRect& aBounds, const WrRect& aOverflow, const WrImageMask* aMask, const float aOpacity, const gfx::Matrix4x4& aTransform, const WrMixBlendMode& aMixBlendMode) { wr_dp_push_stacking_context(mWrState, aBounds, aOverflow, aMask, aOpacity,
--- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -24,34 +24,42 @@ class CompositorBridgeParentBase; } namespace wr { class DisplayListBuilder; class RendererOGL; class RendererEvent; + + class WebRenderAPI { NS_INLINE_DECL_REFCOUNTING(WebRenderAPI); public: /// This can be called on the compositor thread only. static already_AddRefed<WebRenderAPI> Create(bool aEnableProfiler, layers::CompositorBridgeParentBase* aBridge, RefPtr<widget::CompositorWidget>&& aWidget); wr::WindowId GetId() const { return mId; } void GenerateFrame(); void SetRootDisplayList(gfx::Color aBgColor, - wr::Epoch aEpoch, + Epoch aEpoch, LayerSize aViewportSize, - DisplayListBuilder& aBuilder); + WrPipelineId pipeline_id, + WrBuiltDisplayListDescriptor dl_descriptor, + uint8_t *dl_data, + size_t dl_size, + WrAuxiliaryListsDescriptor aux_descriptor, + uint8_t *aux_data, + size_t aux_size); void SetRootPipeline(wr::PipelineId aPipeline); void AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, Range<uint8_t> aBytes); wr::ImageKey AddExternalImageHandle(gfx::IntSize aSize, @@ -103,16 +111,20 @@ public: explicit DisplayListBuilder(wr::PipelineId aId); DisplayListBuilder(DisplayListBuilder&&) = default; ~DisplayListBuilder(); void Begin(const LayerIntSize& aSize); void End(); + void Finalize(WrBuiltDisplayListDescriptor& dl_descriptor, + wr::VecU8& dl_data, + WrAuxiliaryListsDescriptor& aux_descriptor, + wr::VecU8& aux_data); void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects const WrRect& aOverflow, const WrImageMask* aMask, // TODO: needs a wrapper. const float aOpacity, const gfx::Matrix4x4& aTransform, const WrMixBlendMode& aMixBlendMode);
--- a/gfx/webrender_bindings/WebRenderTypes.h +++ b/gfx/webrender_bindings/WebRenderTypes.h @@ -288,12 +288,29 @@ struct ByteBuffer !(memcmp(mData, other.mData, mLength)); } size_t mLength; uint8_t* mData; bool mOwned; }; +struct VecU8 { + WrVecU8 inner; + VecU8() { + inner.data = nullptr; + } + VecU8(VecU8&) = delete; + VecU8(VecU8&& src) { + inner = src.inner; + src.inner.data = nullptr; + } + + ~VecU8() { + if (inner.data) + wr_vec_u8_free(inner); + } +}; + } // namespace wr } // namespace mozilla #endif /* GFX_WEBRENDERTYPES_H */
--- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -6,16 +6,18 @@ use gleam::gl; use webrender_traits::{BorderSide, BorderStyle, BorderRadius, BorderWidths, BorderDetails, NormalBorder}; use webrender_traits::{PipelineId, ClipRegion, PropertyBinding}; use webrender_traits::{Epoch, ExtendMode, ColorF, GlyphInstance, GradientStop, ImageDescriptor}; use webrender_traits::{FilterOp, ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, RendererKind, MixBlendMode}; use webrender_traits::{ExternalImageId, RenderApi, FontKey}; use webrender_traits::{DeviceUintSize, ExternalEvent}; use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform}; use webrender_traits::{BoxShadowClipMode, LayerPixel, ServoScrollRootId, IdNamespace}; +use webrender_traits::{BuiltDisplayListDescriptor, AuxiliaryListsDescriptor}; +use webrender_traits::{BuiltDisplayList, AuxiliaryLists}; use webrender::renderer::{Renderer, RendererOptions}; use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource}; use webrender::{ApiRecordingReceiver, BinaryRecorder}; use app_units::Au; use euclid::TypedPoint2D; extern crate webrender_traits; @@ -72,16 +74,39 @@ impl WrImageDescriptor { stride: if self.stride != 0 { Some(self.stride) } else { None }, format: self.format, is_opaque: self.is_opaque, offset: 0, } } } +#[repr(C)] +pub struct WrVecU8 { + ptr: *mut u8, + length: usize, + capacity: usize +} + +impl WrVecU8 { + fn to_vec(self) -> Vec<u8> { + unsafe { Vec::from_raw_parts(self.ptr, self.length, self.capacity) } + } + fn from_vec(mut v: Vec<u8>) -> WrVecU8 { + let w = WrVecU8{ptr: v.as_mut_ptr(), length: v.len(), capacity: v.capacity()}; + mem::forget(v); + w + } +} + +#[no_mangle] +pub extern fn wr_vec_u8_free(v: WrVecU8) { + v.to_vec(); +} + fn get_proc_address(glcontext_ptr: *mut c_void, name: &str) -> *const c_void{ extern { fn get_proc_address_from_glcontext(glcontext_ptr: *mut c_void, procname: *const c_char) -> *const c_void; } let symbol_name = CString::new(name).unwrap(); let symbol = unsafe { @@ -174,33 +199,70 @@ pub unsafe extern fn wr_api_get_namespac #[no_mangle] pub unsafe extern fn wr_api_delete(api: *mut RenderApi) { let api = Box::from_raw(api); api.shut_down(); } #[no_mangle] +pub unsafe extern fn wr_api_finalize_builder(state: &mut WrState, + dl_descriptor: &mut BuiltDisplayListDescriptor, + dl_data: &mut WrVecU8, + aux_descriptor: &mut AuxiliaryListsDescriptor, + aux_data: &mut WrVecU8) +{ + let frame_builder = mem::replace(&mut state.frame_builder, + WebRenderFrameBuilder::new(state.pipeline_id)); + let (pipeline_id, dl, aux) = frame_builder.dl_builder.finalize(); + //XXX: get rid of the copies here + *dl_data = WrVecU8::from_vec(dl.data().to_owned()); + *dl_descriptor = dl.descriptor().clone(); + *aux_data = WrVecU8::from_vec(aux.data().to_owned()); + *aux_descriptor = aux.descriptor().clone(); +} + +#[no_mangle] pub unsafe extern fn wr_api_set_root_display_list(api: &mut RenderApi, - state: &mut WrState, epoch: Epoch, viewport_width: f32, - viewport_height: f32) { + viewport_height: f32, + pipeline_id: PipelineId, + dl_descriptor: BuiltDisplayListDescriptor, + dl_data: *mut u8, + dl_size: usize, + aux_descriptor: AuxiliaryListsDescriptor, + aux_data: *mut u8, + aux_size: usize) { let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0); - let frame_builder = mem::replace(&mut state.frame_builder, - WebRenderFrameBuilder::new(state.pipeline_id)); // See the documentation of set_root_display_list in api.rs. I don't think // it makes a difference in gecko at the moment(until APZ is figured out) // but I suppose it is a good default. let preserve_frame_state = true; - //let (dl_builder, aux_builder) = fb.dl_builder.finalize(); + + let dl_slice = unsafe { + slice::from_raw_parts(dl_data, dl_size) + }; + let mut dl_vec = Vec::new(); + // XXX: see if we can get rid of the copy here + dl_vec.extend_from_slice(dl_slice); + let dl = BuiltDisplayList::from_data(dl_vec, dl_descriptor); + + let aux_slice = unsafe { + slice::from_raw_parts(aux_data, aux_size) + }; + let mut aux_vec = Vec::new(); + // XXX: see if we can get rid of the copy here + aux_vec.extend_from_slice(aux_slice); + let aux = AuxiliaryLists::from_data(aux_vec, aux_descriptor); + api.set_root_display_list(Some(root_background_color), epoch, LayoutSize::new(viewport_width, viewport_height), - frame_builder.dl_builder.finalize(), + (pipeline_id, dl, aux), preserve_frame_state); } #[no_mangle] pub extern fn wr_api_generate_frame(api: &mut RenderApi) { api.generate_frame(None); }
--- a/gfx/webrender_bindings/webrender_ffi.h +++ b/gfx/webrender_bindings/webrender_ffi.h @@ -336,16 +336,33 @@ struct WrExternalImageHandler struct WrImageDescriptor { WrImageFormat format; uint32_t width; uint32_t height; uint32_t stride; bool is_opaque; }; +struct WrBuiltDisplayListDescriptor { + size_t display_list_items_size; +}; + +struct WrAuxiliaryListsDescriptor { + size_t gradient_stops_size; + size_t complex_clip_regions_size; + size_t filters_size; + size_t glyph_instances_size; +}; + +struct WrVecU8 { + uint8_t *data; + size_t length; + size_t capacity; +}; + // ----- // Functions exposed by the webrender API // ----- // Some useful defines to stub out webrender binding functions for when we // build gecko without webrender. We try to tell the compiler these functions // are unreachable in that case, but VC++ emits a warning if it finds any // unreachable functions invoked from destructors. That warning gets turned into @@ -442,17 +459,24 @@ WR_INLINE void wr_api_delete_image(WrAPI* api, WrImageKey key) WR_FUNC; WR_INLINE void wr_api_set_root_pipeline(WrAPI* api, WrPipelineId pipeline_id) WR_FUNC; WR_INLINE void -wr_api_set_root_display_list(WrAPI* api, WrState* state, WrEpoch epoch, float w, float h) +wr_api_set_root_display_list(WrAPI* api, WrEpoch epoch, float w, float h, + WrPipelineId pipeline_id, + WrBuiltDisplayListDescriptor dl_descriptor, + uint8_t *dl_data, + size_t dl_size, + WrAuxiliaryListsDescriptor aux_descriptor, + uint8_t *aux_data, + size_t aux_size) WR_FUNC; WR_INLINE void wr_api_generate_frame(WrAPI* api) WR_FUNC; WR_INLINE void wr_api_send_external_event(WrAPI* api, uintptr_t evt) @@ -554,13 +578,25 @@ wr_dp_push_box_shadow(WrState* wrState, float blur_radius, float spread_radius, float border_radius, WrBoxShadowClipMode clip_mode) WR_FUNC; WR_INLINE WrIdNamespace wr_api_get_namespace(WrAPI* api) WR_FUNC; +WR_INLINE void +wr_api_finalize_builder(WrState* wrState, + WrBuiltDisplayListDescriptor& dl_descriptor, + WrVecU8& dl_data, + WrAuxiliaryListsDescriptor& aux_descriptor, + WrVecU8& aux_data) +WR_FUNC; + +WR_INLINE void +wr_vec_u8_free(WrVecU8 dl_data) +WR_FUNC; + #undef WR_FUNC #undef WR_DESTRUCTOR_SAFE_FUNC } // extern "C" #endif // WR_h