Skip to content

Commit afbd3b2

Browse files
committed
Optimize ToolLoop with modified regions of pixels
Here we avoid copying and clearing pixels that will not be used in the whole tool loop process. Changes: * Add several member functions in ToolLoop to validate/invalidate regions of source/destination images so we know what regions are safe to use by inks and can be shown in the editor * Add new DocumentObserver::onExposeSpritePixels() member to validate pixels that will be displayed in the editor * Add Ink::needs/createSpecialSourceArea() member functions to validate extra areas for inks like blur or jumble * Add undoers::ModifiedRegion to save the undo information about the modified region * Add ShowHideDrawingCursor class * Change "blur" tool policy from overlap to accumulate (This is a real fix for issue #239)
1 parent 07c7756 commit afbd3b2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1057
-599
lines changed

data/gui.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@
696696
controller="freehand"
697697
pointshape="pixel"
698698
intertwine="as_lines"
699-
tracepolicy="accumulative">
699+
tracepolicy="accumulate">
700700
<tooltip>*
701701
Left-button: Replace/add to current selection.&#10;*
702702
Right-button: Remove from current selection.
@@ -723,7 +723,7 @@
723723
ink="selection"
724724
controller="one_point"
725725
pointshape="floodfill"
726-
tracepolicy="accumulative">
726+
tracepolicy="accumulate">
727727
<tooltip>*
728728
Left-button: Replace/add to current selection.&#10;*
729729
Right-button: Remove from current selection.
@@ -738,7 +738,7 @@
738738
controller="freehand"
739739
pointshape="brush"
740740
intertwine="as_lines"
741-
tracepolicy="accumulative"
741+
tracepolicy="accumulate"
742742
/>
743743
<tool id="spray"
744744
text="Spray Tool"
@@ -757,7 +757,7 @@
757757
controller="freehand"
758758
pointshape="brush"
759759
intertwine="as_lines"
760-
tracepolicy="accumulative"
760+
tracepolicy="accumulate"
761761
default_brush_size="8">
762762
<tooltip>*
763763
Left-button: Erase with the background color in `Background' layer&#10;
@@ -810,7 +810,7 @@
810810
ink="paint"
811811
controller="one_point"
812812
pointshape="floodfill"
813-
tracepolicy="accumulative"
813+
tracepolicy="accumulate"
814814
/>
815815
</group>
816816

@@ -880,7 +880,7 @@
880880
controller="freehand"
881881
pointshape="brush"
882882
intertwine="as_lines"
883-
tracepolicy="accumulative"
883+
tracepolicy="accumulate"
884884
/>
885885
<tool id="polygon"
886886
text="Polygon Tool"
@@ -900,7 +900,7 @@
900900
controller="freehand"
901901
pointshape="brush"
902902
intertwine="as_lines"
903-
tracepolicy="overlap"
903+
tracepolicy="accumulate"
904904
default_brush_size="16"
905905
/>
906906
<tool id="jumble"

src/app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ add_library(app-lib
249249
undoers/dirty_area.cpp
250250
undoers/flip_image.cpp
251251
undoers/image_area.cpp
252+
undoers/modified_region.cpp
252253
undoers/move_layer.cpp
253254
undoers/open_group.cpp
254255
undoers/remap_palette.cpp

src/app/commands/cmd_export_sprite_sheet.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
337337
// destination clipping bounds in Sprite::render() function.
338338
tempImage->clear(0);
339339
sprite->render(tempImage, 0, 0, frame);
340-
resultImage->copy(tempImage, column*sprite->width(), row*sprite->height());
340+
resultImage->copy(tempImage, column*sprite->width(), row*sprite->height(),
341+
0, 0, tempImage->width(), tempImage->height());
341342

342343
if (++column >= columns) {
343344
column = 0;

src/app/commands/cmd_preview.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ class PreviewWindow : public Window {
192192

193193
ImageBufferPtr buf = Editor::getRenderImageBuffer();
194194
m_render.reset(
195-
renderEngine.renderSprite(
196-
0, 0, m_sprite->width(), m_sprite->height(),
195+
renderEngine.renderSprite(m_sprite->bounds(),
197196
m_editor->frame(), Zoom(1, 1), false, false, buf));
198197
}
199198

src/app/document.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ void Document::notifySpritePixelsModified(Sprite* sprite, const gfx::Region& reg
108108
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onSpritePixelsModified, ev);
109109
}
110110

111+
void Document::notifyExposeSpritePixels(Sprite* sprite, const gfx::Region& region)
112+
{
113+
doc::DocumentEvent ev(this);
114+
ev.sprite(sprite);
115+
ev.region(region);
116+
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onExposeSpritePixels, ev);
117+
}
118+
111119
void Document::notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer)
112120
{
113121
doc::DocumentEvent ev(this);

src/app/document.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ namespace app {
9191

9292
void notifyGeneralUpdate();
9393
void notifySpritePixelsModified(Sprite* sprite, const gfx::Region& region);
94+
void notifyExposeSpritePixels(Sprite* sprite, const gfx::Region& region);
9495
void notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer);
9596
void notifyCelMoved(Layer* fromLayer, FrameNumber fromFrame, Layer* toLayer, FrameNumber toFrame);
9697
void notifyCelCopied(Layer* fromLayer, FrameNumber fromFrame, Layer* toLayer, FrameNumber toFrame);

src/app/document_api.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,11 +1093,10 @@ void DocumentApi::flattenLayers(Sprite* sprite)
10931093

10941094
// We have to save the current state of `cel_image' in the undo.
10951095
if (undoEnabled()) {
1096-
Dirty* dirty = new Dirty(cel_image, image, image->bounds());
1097-
dirty->saveImagePixels(cel_image);
1096+
Dirty dirty(cel_image, image, image->bounds());
1097+
dirty.saveImagePixels(cel_image);
10981098
m_undoers->pushUndoer(new undoers::DirtyArea(
1099-
getObjects(), cel_image, dirty));
1100-
delete dirty;
1099+
getObjects(), cel_image, &dirty));
11011100
}
11021101
}
11031102
else {
@@ -1296,10 +1295,9 @@ void DocumentApi::flipImageWithMask(Layer* layer, Image* image, const Mask* mask
12961295

12971296
// Insert the undo operation.
12981297
if (undoEnabled()) {
1299-
base::UniquePtr<Dirty> dirty((new Dirty(image, flippedImage, image->bounds())));
1300-
dirty->saveImagePixels(image);
1301-
1302-
m_undoers->pushUndoer(new undoers::DirtyArea(getObjects(), image, dirty));
1298+
Dirty dirty(image, flippedImage, image->bounds());
1299+
dirty.saveImagePixels(image);
1300+
m_undoers->pushUndoer(new undoers::DirtyArea(getObjects(), image, &dirty));
13031301
}
13041302

13051303
// Copy the flipped image into the image specified as argument.

src/app/settings/ui_settings_impl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,18 +1026,23 @@ class UIToolSettingsImpl
10261026

10271027
tools::ToolBox* toolBox = App::instance()->getToolBox();
10281028
for (int i=0; i<2; ++i) {
1029+
if (m_tool->getTracePolicy(i) != tools::TracePolicy::Accumulate &&
1030+
m_tool->getTracePolicy(i) != tools::TracePolicy::AccumulateUpdateLast) {
1031+
continue;
1032+
}
1033+
10291034
switch (algorithm) {
10301035
case kDefaultFreehandAlgorithm:
10311036
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsLines));
1032-
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
1037+
m_tool->setTracePolicy(i, tools::TracePolicy::Accumulate);
10331038
break;
10341039
case kPixelPerfectFreehandAlgorithm:
10351040
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsPixelPerfect));
1036-
m_tool->setTracePolicy(i, tools::TracePolicyLast);
1041+
m_tool->setTracePolicy(i, tools::TracePolicy::AccumulateUpdateLast);
10371042
break;
10381043
case kDotsFreehandAlgorithm:
10391044
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::None));
1040-
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
1045+
m_tool->setTracePolicy(i, tools::TracePolicy::Accumulate);
10411046
break;
10421047
}
10431048
}

src/app/thumbnail_generator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ class ThumbnailGenerator::Worker {
8585

8686
doc::ImageBufferPtr thumbnail_buffer(new doc::ImageBuffer);
8787
base::UniquePtr<Image> image(renderEngine.renderSprite(
88-
0, 0, sprite->width(), sprite->height(),
89-
FrameNumber(0), Zoom(1, 1), true, false,
88+
sprite->bounds(), FrameNumber(0),
89+
Zoom(1, 1), true, false,
9090
thumbnail_buffer));
9191

9292
// Calculate the thumbnail size

src/app/tools/ink.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
#define APP_TOOLS_INK_H_INCLUDED
2121
#pragma once
2222

23+
namespace gfx {
24+
class Region;
25+
}
26+
2327
namespace app {
2428
namespace tools {
2529

@@ -64,6 +68,12 @@ namespace app {
6468
// Returns true if this ink is used to mark slices
6569
virtual bool isSlice() const { return false; }
6670

71+
// Returns true if this ink needs a special source area. For
72+
// example, blur tool needs one extra pixel to all sides of the
73+
// modified area, so it can use a 3x3 convolution matrix.
74+
virtual bool needsSpecialSourceArea() const { return false; }
75+
virtual void createSpecialSourceArea(const gfx::Region& dirtyArea, gfx::Region& sourceArea) const { }
76+
6777
// It is called when the tool-loop start (generally when the user
6878
// presses a mouse button over a sprite editor)
6979
virtual void prepareInk(ToolLoop* loop) { }

0 commit comments

Comments
 (0)