diff --git a/toonz/sources/include/tools/inputmanager.h b/toonz/sources/include/tools/inputmanager.h
index dad6a50..4696042 100644
--- a/toonz/sources/include/tools/inputmanager.h
+++ b/toonz/sources/include/tools/inputmanager.h
@@ -123,9 +123,9 @@ private:
   inline void release()
     { if ((--m_refCount) <= 0) delete this; }
   inline void lock()
-    { ++m_refCount; }
+    { ++m_lockCount; }
   inline void unlock()
-    { if ((--m_refCount) <= 0) delete this; }
+    { --m_lockCount; }
 
 public:
   bool available;
@@ -159,7 +159,7 @@ public:
   virtual void activate() { }
 
   virtual void modifyTrack(
-    const TTrackP &track,
+    const TTrack &track,
     const TInputSavePoint::Holder &savePoint,
     TTrackList &outTracks );
   virtual void modifyTracks(
@@ -174,8 +174,12 @@ public:
     const THoverList &hovers,
     THoverList &outHovers );
 
+  virtual TRectD calcDrawBoundsHover(const TPointD &hover) { return TRectD(); }
+  virtual TRectD calcDrawBoundsTrack(const TTrack &track) { return TRectD(); }
+  virtual TRectD calcDrawBounds(const TTrackList &tracks, const THoverList &hovers);
+
   virtual void drawHover(const TPointD &hover) { }
-  virtual void drawTrack(const TTrackP &track) { }
+  virtual void drawTrack(const TTrack &track) { }
   virtual void draw(const TTrackList &tracks, const THoverList &hovers);
 
   virtual void deactivate() { }
@@ -234,6 +238,8 @@ public:
       was:            ------O-------O------O------
       become (N = 2): ------O------- */
   virtual void inputPaintPop(int count) { }
+  
+  virtual void inputInvalidateRect(const TRectD &bounds) { }
 };
 
 
@@ -361,6 +367,7 @@ public:
     TTimerTicks ticks);
   void hoverEvent(const THoverList &hovers);
 
+  TRectD calcDrawBounds();
   void draw();
 
   static TInputState::TouchId genTouchId();
diff --git a/toonz/sources/include/tools/modifiers/modifiersegmentation.h b/toonz/sources/include/tools/modifiers/modifiersegmentation.h
index b6466d0..ecdb54a 100644
--- a/toonz/sources/include/tools/modifiers/modifiersegmentation.h
+++ b/toonz/sources/include/tools/modifiers/modifiersegmentation.h
@@ -36,7 +36,7 @@ public:
   TModifierSegmentation(double precision = 1.0);
 
   void modifyTrack(
-    const TTrackP &track,
+    const TTrack &track,
     const TInputSavePoint::Holder &savePoint,
     TTrackList &outTracks ) override;
 };
diff --git a/toonz/sources/include/tools/modifiers/modifiertangents.h b/toonz/sources/include/tools/modifiers/modifiertangents.h
index 12e4059..907aa05 100644
--- a/toonz/sources/include/tools/modifiers/modifiertangents.h
+++ b/toonz/sources/include/tools/modifiers/modifiertangents.h
@@ -38,7 +38,7 @@ public:
   };
 
   void modifyTrack(
-    const TTrackP &track,
+    const TTrack &track,
     const TInputSavePoint::Holder &savePoint,
     TTrackList &outTracks ) override;
 };
diff --git a/toonz/sources/include/tools/modifiers/modifiertest.h b/toonz/sources/include/tools/modifiers/modifiertest.h
index d21c813..f44eb29 100644
--- a/toonz/sources/include/tools/modifiers/modifiertest.h
+++ b/toonz/sources/include/tools/modifiers/modifiertest.h
@@ -29,7 +29,7 @@ public:
   class Handler: public TTrackHandler {
   public:
     std::vector<double> angles;
-    Handler(TTrack &original): TTrackHandler(original) { }
+    Handler(const TTrack &original): TTrackHandler(original) { }
   };
 
   class Modifier: public TTrackModifier {
@@ -49,7 +49,7 @@ public:
   TModifierTest();
 
   void modifyTrack(
-    const TTrackP &track,
+    const TTrack &track,
     const TInputSavePoint::Holder &savePoint,
     TTrackList &outTracks ) override;
 };
diff --git a/toonz/sources/include/tools/track.h b/toonz/sources/include/tools/track.h
index 16331f9..0ff907a 100644
--- a/toonz/sources/include/tools/track.h
+++ b/toonz/sources/include/tools/track.h
@@ -114,9 +114,9 @@ public:
 
 class DVAPI TTrackHandler : public TSmartObject {
 public:
-  TTrack &original;
+  const TTrack &original;
   std::vector<TTrackP> tracks;
-  TTrackHandler(TTrack &original):
+  TTrackHandler(const TTrack &original):
     original(original) { }
 };
 
@@ -128,7 +128,7 @@ public:
 class DVAPI TTrackModifier : public TSmartObject {
 public:
     TTrackHandler &handler;
-    TTrack &original;
+    const TTrack &original;
     const double timeOffset;
 
     explicit TTrackModifier(TTrackHandler &handler, double timeOffset = 0.0):
@@ -160,9 +160,9 @@ public:
   const bool hasTilt;
   const TTrackModifierP modifier;
 
-  TTrackHandlerP handler;
-  int pointsRemoved;
-  int pointsAdded;
+  mutable TTrackHandlerP handler;
+  mutable int pointsRemoved;
+  mutable int pointsAdded;
 
 private:
   TTrackPointList m_points;
@@ -181,7 +181,7 @@ public:
 
   explicit TTrack(const TTrackModifierP &modifier);
 
-  inline TTrack* original() const
+  inline const TTrack* original() const
     { return modifier ? &modifier->original : NULL; }
   inline double timeOffset() const
     { return modifier ? modifier->timeOffset : 0.0; }
@@ -191,7 +191,6 @@ public:
     { return pointsAdded != 0 || pointsRemoved != 0; }
 
   const TTrack* root() const;
-  TTrack* root();
   int level() const;
 
   inline int clampIndex(int index) const
diff --git a/toonz/sources/tnztools/fullcolorbrushtool.cpp b/toonz/sources/tnztools/fullcolorbrushtool.cpp
index 9f8a3b3..848a205 100644
--- a/toonz/sources/tnztools/fullcolorbrushtool.cpp
+++ b/toonz/sources/tnztools/fullcolorbrushtool.cpp
@@ -660,6 +660,7 @@ void FullColorBrushTool::draw() {
 
     glPopAttrib();
   }
+  m_inputmanager.draw();
 }
 
 //--------------------------------------------------------------------------------------------------------------
diff --git a/toonz/sources/tnztools/inputmanager.cpp b/toonz/sources/tnztools/inputmanager.cpp
index 1f3aa55..1d9af83 100644
--- a/toonz/sources/tnztools/inputmanager.cpp
+++ b/toonz/sources/tnztools/inputmanager.cpp
@@ -2,6 +2,9 @@
 
 #include <tools/inputmanager.h>
 
+// TnzCore includes
+#include <tgl.h>
+
 
 //*****************************************************************************************
 //    static members
@@ -24,44 +27,44 @@ TInputModifier::setManager(TInputManager *manager) {
 
 void
 TInputModifier::modifyTrack(
-  const TTrackP &track,
+  const TTrack &track,
   const TInputSavePoint::Holder &savePoint,
   TTrackList &outTracks )
 {
-  if (!track->handler) {
-      track->handler = new TTrackHandler(*track);
-      track->handler->tracks.push_back(
+  if (!track.handler) {
+      track.handler = new TTrackHandler(track);
+      track.handler->tracks.push_back(
         new TTrack(
-          new TTrackModifier(*track->handler) ));
+          new TTrackModifier(*track.handler) ));
   }
 
   outTracks.insert(
     outTracks.end(),
-    track->handler->tracks.begin(),
-    track->handler->tracks.end() );
-  if (!track->changed())
+    track.handler->tracks.begin(),
+    track.handler->tracks.end() );
+  if (!track.changed())
     return;
 
-  int start = track->size() - track->pointsAdded;
+  int start = track.size() - track.pointsAdded;
   if (start < 0) start = 0;
 
-  for(TTrackList::const_iterator ti = track->handler->tracks.begin(); ti != track->handler->tracks.end(); ++ti) {
+  for(TTrackList::const_iterator ti = track.handler->tracks.begin(); ti != track.handler->tracks.end(); ++ti) {
     TTrack &subTrack = **ti;
 
     // remove points
-    if (start < track->size()) {
+    if (start < track.size()) {
       subTrack.pointsRemoved += subTrack.size() - start;
       subTrack.truncate(start);
     }
 
     // add points
-    for(int i = start; i < track->size(); ++i)
+    for(int i = start; i < track.size(); ++i)
       subTrack.push_back( subTrack.modifier->calcPoint(i) );
     subTrack.pointsAdded += subTrack.size() - start;
   }
 
-  track->pointsRemoved = 0;
-  track->pointsAdded = 0;
+  track.pointsRemoved = 0;
+  track.pointsAdded = 0;
 }
 
 
@@ -72,7 +75,7 @@ TInputModifier::modifyTracks(
     TTrackList &outTracks )
 {
   for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i)
-    modifyTrack(*i, savePoint, outTracks);
+    modifyTrack(**i, savePoint, outTracks);
 }
 
 
@@ -95,10 +98,21 @@ TInputModifier::modifyHovers(
 }
 
 
+TRectD
+TInputModifier::calcDrawBounds(const TTrackList &tracks, const THoverList &hovers) {
+  TRectD bounds;
+  for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i)
+    bounds += calcDrawBoundsTrack(**i);
+  for(std::vector<TPointD>::const_iterator i = hovers.begin(); i != hovers.end(); ++i)
+    bounds += calcDrawBoundsHover(*i);
+  return bounds;
+}
+
+
 void
 TInputModifier::draw(const TTrackList &tracks, const THoverList &hovers) {
   for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i)
-    drawTrack(*i);
+    drawTrack(**i);
   for(THoverList::const_iterator i = hovers.begin(); i != hovers.end(); ++i)
     drawHover(*i);
 }
@@ -314,6 +328,7 @@ TInputManager::paintTracks() {
     }
 
     // is paint finished?
+    newSavePoint.unlock();
     if (newSavePoint.isFree()) {
       newSavePoint.savePoint()->available = false;
       if (allFinished) {
@@ -452,8 +467,12 @@ TInputManager::modifierDeactivate(const TInputModifierP &modifier) {
 
 
 void
-TInputManager::processTracks()
-  { paintTracks(); }
+TInputManager::processTracks() {
+  paintTracks();
+  TRectD bounds = calcDrawBounds();
+  if (!bounds.isEmpty())
+    m_handler->inputInvalidateRect(bounds);
+}
 
 
 void
@@ -602,40 +621,59 @@ TInputManager::hoverEvent(const THoverList &hovers) {
 }
 
 
+TRectD
+TInputManager::calcDrawBounds() {
+  TRectD bounds;
+  for(int i = 0; i < (int)m_modifiers.size(); ++i)
+    bounds += m_modifiers[i]->calcDrawBounds(m_tracks[i], m_hovers[i]);
+
+  if (m_savePointsSent < (int)m_savePoints.size()) {
+    for(TTrackList::const_iterator ti = getOutputTracks().begin(); ti != getOutputTracks().end(); ++ti) {
+      TTrack &track = **ti;
+      if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) {
+        int start = handler->saves[m_savePointsSent] - 1;
+        if (start < 0) start = 0;
+        if (start + 1 < track.size())
+          for(int i = start + 1; i < track.size(); ++i)
+            bounds += boundingBox(track[i-1].position, track[i].position);
+      }
+    }
+  }
+
+  if (!bounds.isEmpty())
+    bounds.enlarge(2.0);
+  
+  return bounds;
+}
+
+
 void
 TInputManager::draw() {
-  // TODO: paint
-
   // paint not sent sub-tracks
   if (m_savePointsSent < (int)m_savePoints.size()) {
-    //context.Save();
-    //penPreview.apply(context);
-    for(TTrackList::const_iterator i = getOutputTracks().begin(); i != getOutputTracks().end(); ++i) {
-      TTrack &track = **i;
+    glPushAttrib(GL_ALL_ATTRIB_BITS);
+    tglEnableBlending();
+    tglEnableLineSmooth(true, 0.5);
+    for(TTrackList::const_iterator ti = getOutputTracks().begin(); ti != getOutputTracks().end(); ++ti) {
+      TTrack &track = **ti;
       if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) {
         int start = handler->saves[m_savePointsSent] - 1;
         if (start < 0) start = 0;
-        if (start < track.size()) {
-          //Drawing.Color color = penPreview.color;
+        if (start + 1 < track.size()) {
           int level = m_savePointsSent;
-
-          //color.apply(context);
-          //context.MoveTo(track[start].position.x, track.points[start].position.y);
+          double alpha = 1.0;
+          glColor4d(1.0, 1.0, 1.0, alpha);
           for(int i = start + 1; i < track.size(); ++i) {
             while(level < (int)handler->saves.size() && handler->saves[level] <= i) {
-              //context.Stroke();
-              //context.MoveTo(track[i-1].position.x, track[i-1].position.y);
-              //color.a *= levelAlpha;
-              //color.apply(context);
+              glColor4d(1.0, 1.0, 1.0, alpha *= 1.0);
               ++level;
             }
-            //context.LineTo(track[i].position.x, track[i].position.y);
+            tglDrawDoubleSegment(track[i-1].position, track[i].position);
           }
         }
       }
     }
-    //context.Stroke();
-    //context.Restore();
+    glPopAttrib();
   }
 
   // paint modifiers
diff --git a/toonz/sources/tnztools/modifiersegmentation.cpp b/toonz/sources/tnztools/modifiersegmentation.cpp
index ec483fe..6069bb9 100644
--- a/toonz/sources/tnztools/modifiersegmentation.cpp
+++ b/toonz/sources/tnztools/modifiersegmentation.cpp
@@ -38,25 +38,25 @@ TModifierSegmentation::addSegments(
 
 void
 TModifierSegmentation::modifyTrack(
-  const TTrackP &track,
+  const TTrack &track,
   const TInputSavePoint::Holder &savePoint,
   TTrackList &outTracks )
 {
-  if (!track->handler) {
-    track->handler = new TTrackHandler(*track);
-    track->handler->tracks.push_back(
+  if (!track.handler) {
+    track.handler = new TTrackHandler(track);
+    track.handler->tracks.push_back(
       new TTrack(
-        new TTrackModifier(*track->handler) ));
+        new TTrackModifier(*track.handler) ));
   }
 
-  if (!track->changed() || track->handler->tracks.empty())
+  if (!track.changed() || track.handler->tracks.empty())
     return;
 
-  TTrack &subTrack = *track->handler->tracks.front();
-  outTracks.push_back(track->handler->tracks.front());
+  TTrack &subTrack = *track.handler->tracks.front();
+  outTracks.push_back(track.handler->tracks.front());
 
   // remove points
-  int start = track->size() - track->pointsAdded;
+  int start = track.size() - track.pointsAdded;
   if (start < 0) start = 0;
   int subStart = subTrack.floorIndex(subTrack.indexByOriginalIndex(start));
   if (subStart < 0) subStart = 0;
@@ -72,13 +72,13 @@ TModifierSegmentation::modifyTrack(
 
   // add points
   TTrackPoint p0 = subTrack.modifier->calcPoint(start - 1);
-  for(int i = start; i < track->size(); ++i) {
+  for(int i = start; i < track.size(); ++i) {
     TTrackPoint p1 = subTrack.modifier->calcPoint(i);
     addSegments(subTrack, p0, p1);
     p0 = p1;
   }
   subTrack.pointsAdded += subTrack.size() - subStart;
 
-  track->pointsRemoved = 0;
-  track->pointsAdded = 0;
+  track.pointsRemoved = 0;
+  track.pointsAdded = 0;
 }
diff --git a/toonz/sources/tnztools/modifiertangents.cpp b/toonz/sources/tnztools/modifiertangents.cpp
index c7c9f0f..485728b 100644
--- a/toonz/sources/tnztools/modifiertangents.cpp
+++ b/toonz/sources/tnztools/modifiertangents.cpp
@@ -32,42 +32,42 @@ TModifierTangents::Modifier::calcPoint(double originalIndex) {
 
 void
 TModifierTangents::modifyTrack(
-  const TTrackP &track,
+  const TTrack &track,
   const TInputSavePoint::Holder &savePoint,
   TTrackList &outTracks )
 {
-  if (!track->handler) {
-    track->handler = new TTrackHandler(*track);
-    track->handler->tracks.push_back(
+  if (!track.handler) {
+    track.handler = new TTrackHandler(track);
+    track.handler->tracks.push_back(
       new TTrack(
-        new Modifier(*track->handler) ));
+        new Modifier(*track.handler) ));
   }
 
-  if (track->handler->tracks.empty())
+  if (track.handler->tracks.empty())
     return;
 
-  TTrack &subTrack = *track->handler->tracks.front();
+  TTrack &subTrack = *track.handler->tracks.front();
   Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer());
   if (!modifier)
     return;
 
-  outTracks.push_back(track->handler->tracks.front());
+  outTracks.push_back(track.handler->tracks.front());
 
-  if ( !track->changed()
-    && track->size() == subTrack.size()
-    && track->size() == (int)modifier->tangents.size() )
+  if ( !track.changed()
+    && track.size() == subTrack.size()
+    && track.size() == (int)modifier->tangents.size() )
       return;
 
-  if (!track->changed() && subTrack.size() == track->size() - 1) {
+  if (!track.changed() && subTrack.size() == track.size() - 1) {
     // add temporary point
     modifier->tangents.push_back(TTrackTangent());
-    subTrack.push_back(track->back());
+    subTrack.push_back(track.back());
     ++subTrack.pointsAdded;
   } else {
     // apply permanent changes
 
     // remove points
-    int start = track->size() - track->pointsAdded;
+    int start = track.size() - track.pointsAdded;
     if (start < 0) start = 0;
     if (start > 1) --start;
     if (start < subTrack.size()) {
@@ -83,15 +83,15 @@ TModifierTangents::modifyTrack(
     int index = start;
     if (index == 0) {
       modifier->tangents.push_back(TTrackTangent());
-      subTrack.push_back(track->back());
+      subTrack.push_back(track.back());
       ++index;
     }
 
     // add points with tangents
-    while(index < track->size() - 1) {
-      const TTrackPoint &p0 = (*track)[index-1];
-      const TTrackPoint &p1 = (*track)[index];
-      const TTrackPoint &p2 = (*track)[index+1];
+    while(index < track.size() - 1) {
+      const TTrackPoint &p0 = track[index-1];
+      const TTrackPoint &p1 = track[index];
+      const TTrackPoint &p2 = track[index+1];
       double dt = p2.time - p0.time;
       double k = dt > TTrack::epsilon ? (p1.time - p0.time)/dt : 0.5;
       TTrackTangent tangent(
@@ -103,17 +103,17 @@ TModifierTangents::modifyTrack(
       ++index;
     }
 
-    track->pointsRemoved = 0;
-    track->pointsAdded = 0;
+    track.pointsRemoved = 0;
+    track.pointsAdded = 0;
     subTrack.pointsAdded += index - start;
 
     // release previous key point
     modifier->savePoint.reset();
 
-    if (track->finished()) {
+    if (track.finished()) {
       // finish
       modifier->tangents.push_back(TTrackTangent());
-      subTrack.push_back(track->back());
+      subTrack.push_back(track.back());
       ++subTrack.pointsAdded;
     } else {
       // save key point
diff --git a/toonz/sources/tnztools/modifiertest.cpp b/toonz/sources/tnztools/modifiertest.cpp
index a52ce6c..fd7a35f 100644
--- a/toonz/sources/tnztools/modifiertest.cpp
+++ b/toonz/sources/tnztools/modifiertest.cpp
@@ -66,28 +66,28 @@ TModifierTest::TModifierTest():
 
 void
 TModifierTest::modifyTrack(
-  const TTrackP &track,
+  const TTrack &track,
   const TInputSavePoint::Holder &savePoint,
   TTrackList &outTracks )
 {
   const double segmentSize = M_PI/180.0*10.0;
 
-  if (!track->handler) {
-    if (track->getCurrentKeyState().isPressed(TKey(Qt::Key_Alt))) {
+  if (!track.handler) {
+    if (track.getKeyState(track.front().time).isPressed(TKey(Qt::Key_Alt))) {
       // TModifierTest::Handler for spiro
-      track->handler = new Handler(*track);
+      track.handler = new Handler(track);
       for(int i = 0; i < count; ++i)
-        track->handler->tracks.push_back(
+        track.handler->tracks.push_back(
           new TTrack(
             new Modifier(
-              *track->handler,
+              *track.handler,
               i*2.0*M_PI/(double)count,
               radius,
               2.0 )));
     }
   }
 
-  Handler *handler = dynamic_cast<Handler*>(track->handler.getPointer());
+  Handler *handler = dynamic_cast<Handler*>(track.handler.getPointer());
   if (!handler) {
     TInputModifier::modifyTrack(track, savePoint, outTracks);
     return;
@@ -95,12 +95,12 @@ TModifierTest::modifyTrack(
 
   outTracks.insert(
     outTracks.end(),
-    track->handler->tracks.begin(),
-    track->handler->tracks.end() );
-  if (!track->changed())
+    track.handler->tracks.begin(),
+    track.handler->tracks.end() );
+  if (!track.changed())
     return;
 
-  int start = track->size() - track->pointsAdded;
+  int start = track.size() - track.pointsAdded;
   if (start < 0) start = 0;
 
   // remove angles
@@ -110,11 +110,11 @@ TModifierTest::modifyTrack(
       handler->angles.end() );
 
   // add angles
-  for(int i = start; i < track->size(); ++i) {
+  for(int i = start; i < track.size(); ++i) {
     if (i > 0) {
-      double dl = (*track)[i].length - (*track)[i-1].length;
-      double da = (*track)[i].pressure > TTrack::epsilon
-                ? dl/(2.0*radius*(*track)[i].pressure) : 0.0;
+      double dl = track[i].length - track[i-1].length;
+      double da = track[i].pressure > TTrack::epsilon
+                ? dl/(2.0*radius*track[i].pressure) : 0.0;
       handler->angles.push_back(handler->angles[i-1] + da);
     } else {
       handler->angles.push_back(0.0);
@@ -137,7 +137,7 @@ TModifierTest::modifyTrack(
     }
 
     // add points
-    for(int i = start; i < track->size(); ++i) {
+    for(int i = start; i < track.size(); ++i) {
       if (i > 0) {
         double prevAngle = handler->angles[i-1];
         double nextAngle = handler->angles[i];
@@ -153,7 +153,7 @@ TModifierTest::modifyTrack(
     subTrack.pointsAdded += subTrack.size() - subStart;
   }
 
-  track->pointsRemoved = 0;
-  track->pointsAdded = 0;
+  track.pointsRemoved = 0;
+  track.pointsAdded = 0;
 }
 
diff --git a/toonz/sources/tnztools/track.cpp b/toonz/sources/tnztools/track.cpp
index 6193c8a..ab30870 100644
--- a/toonz/sources/tnztools/track.cpp
+++ b/toonz/sources/tnztools/track.cpp
@@ -63,10 +63,6 @@ const TTrack*
 TTrack::root() const
   { return original() ? original()->root() : this; }
 
-TTrack*
-TTrack::root()
-  { return original() ? original()->root() : this; }
-
 int
 TTrack::level() const
   { return original() ? original()->level() + 1 : 0; }