-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Separate rendering part from specification part for layers #8797
Conversation
9194b7a
to
3ab7f47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall! The most significant feedback I have is about ownership of the Layer::Impl
-- I don't think we need to introduce shared pointers yet.
Public LayerType
enum is fine. 👍 on moving rendering related source files.
include/mbgl/style/layer.hpp
Outdated
@@ -117,14 +111,12 @@ class Layer : public mbgl::util::noncopyable { | |||
void setMaxZoom(float) const; | |||
|
|||
// Private implementation | |||
const std::unique_ptr<Impl> baseImpl; | |||
const std::shared_ptr<Impl> baseImpl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we go the route of using immutable objects, we may use shared pointers internally (albeit probably behind an Immutable<T>
class template), but for now let's keep the Layer
owning the Impl
uniquely. RenderLayer
s should never outlive their associated Layer
and can therefore have a regular non-owning const Impl&
reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RenderLayers
should never outlive their associatedLayer
Just realized this isn't the case. RenderLayer
s copied into the worker may outlive the Layer
. Need to think about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per chat: good solution is probably to continue to pass copies of Layer
s to the worker, rather than RenderLayer
s. The worker can then create its own RenderLayer
s, allowing us to preserve the invariant "RenderLayers
never outlive their associated Layer
" and avoid (unintentionally) sharing a Layer::Impl
between the main thread and worker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfirebaugh If we copy layers in GeometryTile
to pass to GeometryTileWorker::setLayers
and then create RenderLayer
s from that in the GeometryTileWorker
; we would be copying the associated Impl
twice right? In that case, maybe we should revert the changes to GeometryTileWorker
and group_by_layout.hpp to continue to work on Layer
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfirebaugh I Fixed up ownership as discussed above in 7f0ad32. I Left the pointers to the concrete Implementations in the subclasses as is (const style::FooLayer::Impl* const impl;
as opposed to a const style::FooLayer::Impl&
) to avoid modifying all call sites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfirebaugh This does not work as hoped. Since the Layer::Impl
subclasses no longer contain a reference to the cascaded/evaluated paint properties, the render layers created in the GeometryTileWorker
start with a blank copy, disjointed from the copy in the render layers in the style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we actually need the cascaded/evaluated paint properties? Evaluated paint properties can be generated from the cascaded paint properties plus tile zoom level. With regards to cascaded properties, cascading would mainly be needed in supporting the combination of data-driven paint properties with style classes, which I don't think we support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfirebaugh I figured this must be the reason that all the property-function render tests are failing. It makes me think it's because there is some state now not copied over / held on to when creating the buckets (since that is the main change).
If I understand correctly; in the painter the paint property binders (created in the bucket from the copied paint properties) and the evaluated paint properties form the Layer::Impl
come together and then in the program the current properties are bound to attributes and interpolated from the values the binders were originally created with right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c397125 fixes the render tests.
It's true that the current paint properties are inspected at render time as well as the binder, but it's either one or the other:
- If the current value is a constant or camera function, it's used and the value the binder was originally created from is ignored.
- Otherwise, the value the binder was originally created from is used, and the current value is ignored.
src/mbgl/layout/symbol_layout.cpp
Outdated
{ | ||
|
||
const SymbolLayer::Impl& leader = *layers.at(0)->as<SymbolLayer>()->impl; | ||
const auto& leader = *layers.at(0)->as<RenderSymbolLayer>()->impl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use auto
unless the type is written elsewhere in the same line (e.g. assigning from the result of std::make_unique
) or is uninteresting (iterators). Here explicitly specifying SymbolLayer::Impl
aids readability.
src/mbgl/style/layer_impl.hpp
Outdated
@@ -42,6 +36,7 @@ class Layer::Impl { | |||
|
|||
// Create a new layer with the specified `id` and `sourceID`. All other properties | |||
// are copied from this layer. | |||
// TODO: evaluate if this still meets expectations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy
is only used in one place: StyleSourcedAnnotationImpl
, which is code supporting a pre-runtime styling feature that we should remove. We can save that for a separate change though.
src/mbgl/style/style.cpp
Outdated
} | ||
|
||
// TODO | ||
// auto layer = std::move(*it); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be deleted. When a custom layer is removed, the custom layer deinitialize function only needs to be called once.
|
||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override; | ||
std::unique_ptr<SymbolLayout> createLayout(const BucketParameters&, const std::vector<const Layer*>&, | ||
// TODO move to RenderSymbolLayer? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should. This is the symbol layer equivalent of createBucket
.
c397125
to
4fde1da
Compare
4fde1da
to
2677a3a
Compare
@jfirebaugh I update the pr with your review comments. I refrained from moving more files to the renderer package for now as the ones I had my eye on are all referred to from |
In an attempt to separate rendering on a different thread..
Open ends:
Use ofstd::enable_shared_from_this
eg here so we can do thisLayer::Type
in a separate header to re-use it forRenderLayer
subclasses. This makes it public though.Maybe we should just duplicate it, especially if we want this to be part of the public API./renderer
package:cc @jfirebaugh