Add parallelization to transform calculation
This commit is contained in:
parent
726368fd6f
commit
e750d857da
3 changed files with 43 additions and 21 deletions
|
|
@ -88,12 +88,15 @@ void CanvasComponentContainer::load_file(cereal::PortableBinaryInputArchive& a,
|
|||
}
|
||||
|
||||
void CanvasComponentContainer::draw(SkCanvas* canvas, const DrawData& drawData) const {
|
||||
if(should_draw(drawData)) {
|
||||
canvas->save();
|
||||
canvas_do_transform(canvas, calculate_draw_transform(drawData));
|
||||
get_comp().draw(canvas, drawData);
|
||||
canvas->restore();
|
||||
}
|
||||
if(should_draw(drawData))
|
||||
draw_with_transform(canvas, drawData, calculate_draw_transform(drawData));
|
||||
}
|
||||
|
||||
void CanvasComponentContainer::draw_with_transform(SkCanvas* canvas, const DrawData& drawData, const TransformDrawData& transformDrawData) const {
|
||||
canvas->save();
|
||||
canvas_do_transform(canvas, transformDrawData);
|
||||
get_comp().draw(canvas, drawData);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
void CanvasComponentContainer::commit_update(DrawingProgram& drawP) {
|
||||
|
|
@ -132,7 +135,7 @@ bool CanvasComponentContainer::collides_with_cam_coords(const CoordSpaceHelper&
|
|||
bool CanvasComponentContainer::collides_with(const CoordSpaceHelper& camCoords, const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam) const {
|
||||
if((camCoords.inverseScale << COMP_MAX_SHIFT_BEFORE_STOP_COLLISIONS) < coords.inverseScale) // Object is too large, just dismiss the collision
|
||||
return false;
|
||||
else if((camCoords.inverseScale >> COMP_COLLIDE_MIN_SHIFT_TINY) >= coords.inverseScale)
|
||||
else if(coords.inverseScale < (camCoords.inverseScale >> COMP_COLLIDE_MIN_SHIFT_TINY))
|
||||
return SCollision::collide(checkAgainstCam, camCoords.to_space(worldAABB.value().min));
|
||||
else {
|
||||
auto c = checkAgainstWorld.transform<float>(
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ class CanvasComponentContainer {
|
|||
std::unique_ptr<CanvasComponent> obj;
|
||||
void scale_up(const WorldScalar& scaleUpAmount);
|
||||
};
|
||||
|
||||
struct TransformDrawData {
|
||||
Vector2f translation;
|
||||
float rotation;
|
||||
float scale;
|
||||
};
|
||||
std::optional<TransformDrawData> transformHolder; // Can be used to store transforms when calculating transforms in parallel
|
||||
|
||||
CanvasComponentContainer();
|
||||
CanvasComponentContainer(NetworkingObjects::NetObjManager& objMan, CanvasComponentType type);
|
||||
|
|
@ -45,6 +52,8 @@ class CanvasComponentContainer {
|
|||
CanvasComponent& get_comp() const;
|
||||
SCollision::AABB<WorldScalar> get_world_bounds() const;
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData) const;
|
||||
void draw_with_transform(SkCanvas* canvas, const DrawData& drawData, const TransformDrawData& transformDrawData) const;
|
||||
TransformDrawData calculate_draw_transform(const DrawData& drawData) const;
|
||||
void commit_update(DrawingProgram& drawP);
|
||||
void commit_transform_dont_invalidate_cache(); // Must be thread safe
|
||||
void commit_transform(DrawingProgram& drawP);
|
||||
|
|
@ -66,16 +75,9 @@ class CanvasComponentContainer {
|
|||
|
||||
static void write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<CanvasComponentContainer>& o, cereal::PortableBinaryOutputArchive& a);
|
||||
|
||||
struct TransformDrawData {
|
||||
Vector2f translation;
|
||||
float rotation;
|
||||
float scale;
|
||||
};
|
||||
|
||||
unsigned get_mipmap_level(const DrawData& drawData) const;
|
||||
CanvasComponent* allocate_comp(CanvasComponentType type);
|
||||
void canvas_do_transform(SkCanvas* canvas, const TransformDrawData& transformData) const;
|
||||
TransformDrawData calculate_draw_transform(const DrawData& drawData) const;
|
||||
void calculate_world_bounds();
|
||||
|
||||
std::optional<SCollision::AABB<WorldScalar>> worldAABB;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "DrawingProgram.hpp"
|
||||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "Helpers/Parallel.hpp"
|
||||
#include "Layers/DrawingProgramLayerManager.hpp"
|
||||
|
||||
#ifdef USE_SKIA_BACKEND_GRAPHITE
|
||||
|
|
@ -424,8 +425,10 @@ void DrawingProgramCache::draw_components_to_canvas(SkCanvas* canvas, const Draw
|
|||
}
|
||||
}
|
||||
}
|
||||
if(node) // Not the "unsorted components" node (which is nullptr)
|
||||
if(node && node->coords.inverseScale > (drawData.cam.c.inverseScale >> CanvasComponentContainer::COMP_MIN_SHIFT_BEFORE_DISAPPEAR)) // Not the "unsorted components" node (which is nullptr)
|
||||
uncachedNodes.emplace_back(node);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
@ -448,21 +451,35 @@ void DrawingProgramCache::recursive_draw_layer_item_to_canvas(const DrawingProgr
|
|||
}
|
||||
else {
|
||||
std::vector<CanvasComponentContainer::ObjInfo*> compsToDraw;
|
||||
for(auto& c : unsortedComponents) {
|
||||
if(c->obj->parentLayer == &layerListItem && (!drawBounds.has_value() || SCollision::collide(drawBounds.value(), c->obj->get_world_bounds())))
|
||||
compsToDraw.emplace_back(c);
|
||||
}
|
||||
parallel_loop_container(nodesToDraw, [&](auto& node) {
|
||||
std::for_each(node->components.begin(), node->components.end(), [&](auto& c) {
|
||||
if(c->obj->parentLayer == &layerListItem && (!drawBounds.has_value() || SCollision::collide(drawBounds.value(), c->obj->get_world_bounds())) && c->obj->should_draw(drawData))
|
||||
c->obj->transformHolder = c->obj->calculate_draw_transform(drawData);
|
||||
else
|
||||
c->obj->transformHolder = std::nullopt;
|
||||
});
|
||||
});
|
||||
parallel_loop_container(unsortedComponents, [&](auto& c) {
|
||||
if(c->obj->parentLayer == &layerListItem && (!drawBounds.has_value() || SCollision::collide(drawBounds.value(), c->obj->get_world_bounds())) && c->obj->should_draw(drawData))
|
||||
c->obj->transformHolder = c->obj->calculate_draw_transform(drawData);
|
||||
else
|
||||
c->obj->transformHolder = std::nullopt;
|
||||
});
|
||||
for(auto& node : nodesToDraw) {
|
||||
for(auto& c : node->components) {
|
||||
if(c->obj->parentLayer == &layerListItem && (!drawBounds.has_value() || SCollision::collide(drawBounds.value(), c->obj->get_world_bounds())))
|
||||
if(c->obj->transformHolder.has_value())
|
||||
compsToDraw.emplace_back(c);
|
||||
}
|
||||
}
|
||||
for(auto& c : unsortedComponents) {
|
||||
if(c->obj->transformHolder.has_value())
|
||||
compsToDraw.emplace_back(c);
|
||||
}
|
||||
std::sort(compsToDraw.begin(), compsToDraw.end(), [](auto& a, auto& b) {
|
||||
return a->pos < b->pos;
|
||||
});
|
||||
for(auto& c : compsToDraw)
|
||||
c->obj->draw(canvas, drawData);
|
||||
c->obj->draw_with_transform(canvas, drawData, c->obj->transformHolder.value());
|
||||
}
|
||||
canvas->restore();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue