diff --git a/__init__.py b/__init__.py
index 398aa020f6c0e489d23502d33b17c21593d47548..5c260d1a95fe52a2ab83038c6e96a8f58152d110 100644
--- a/__init__.py
+++ b/__init__.py
@@ -18,10 +18,10 @@ if 'linux' in sys.platform:  ## linux has numerous bugs in opengl implementation
 elif 'darwin' in sys.platform: ## openGL greatly speeds up display on mac
     useOpenGL = True
 else:
-    useOpenGL = True  ## on windows there's a more even performance / bugginess tradeoff. 
+    useOpenGL = False  ## on windows there's a more even performance / bugginess tradeoff. 
                 
 CONFIG_OPTIONS = {
-    'useOpenGL': None,   ## by default, this is platform-dependent (see widgets/GraphicsView). Set to True or False to explicitly enable/disable opengl.
+    'useOpenGL': useOpenGL,   ## by default, this is platform-dependent (see widgets/GraphicsView). Set to True or False to explicitly enable/disable opengl.
     'leftButtonPan': True  ## if false, left button drags a rubber band for zooming in viewbox
 }
 
diff --git a/examples/PlotSpeedTest.py b/examples/PlotSpeedTest.py
index b695bd860d7d3b2c9cf664bcef2c5e32d4bed8fa..212734a198bcc4da7ad48791361af45b0d5b54b0 100644
--- a/examples/PlotSpeedTest.py
+++ b/examples/PlotSpeedTest.py
@@ -1,14 +1,14 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 ## Add path to library (just for examples; you do not need this)
-import sys, os, time
+import sys, os
 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
 
 
 from pyqtgraph.Qt import QtGui, QtCore
 import numpy as np
 import pyqtgraph as pg
-
+from pyqtgraph.ptime import time
 #QtGui.QApplication.setGraphicsSystem('raster')
 app = QtGui.QApplication([])
 #mw = QtGui.QMainWindow()
@@ -18,15 +18,22 @@ p = pg.plot()
 p.setRange(QtCore.QRectF(0, -10, 5000, 20)) 
 p.setLabel('bottom', 'Index', units='B')
 curve = p.plot()
+
+#curve.setFillBrush((0, 0, 100, 100))
+#curve.setFillLevel(0)
+
+#lr = pg.LinearRegionItem([100, 4900])
+#p.addItem(lr)
+
 data = np.random.normal(size=(50,5000))
 ptr = 0
-lastTime = time.time()
+lastTime = time()
 fps = None
 def update():
     global curve, data, ptr, p, lastTime, fps
     curve.setData(data[ptr%10])
     ptr += 1
-    now = time.time()
+    now = time()
     dt = now - lastTime
     lastTime = now
     if fps is None:
diff --git a/examples/VideoSpeedTest.py b/examples/VideoSpeedTest.py
index 49d4c715d6e31575b1388f0f63abfdca3ff887b4..57d8aacce0dac4c409f3068832776f087f8d8191 100644
--- a/examples/VideoSpeedTest.py
+++ b/examples/VideoSpeedTest.py
@@ -25,6 +25,8 @@ win.show()
 ui.maxSpin1.setOpts(value=255, step=1)
 ui.minSpin1.setOpts(value=0, step=1)
 
+#ui.graphicsView.useOpenGL()  ## buggy, but you can try it if you need extra speed.
+
 vb = pg.ViewBox()
 ui.graphicsView.setCentralItem(vb)
 vb.setAspectLocked()
diff --git a/graphicsItems/GradientEditorItem.py b/graphicsItems/GradientEditorItem.py
index d3eaaf869530bd8565a456692dec57dbb8ae20ba..c06995c7a429e99e5f5fb471add259052d6ceca2 100644
--- a/graphicsItems/GradientEditorItem.py
+++ b/graphicsItems/GradientEditorItem.py
@@ -467,7 +467,19 @@ class GradientEditorItem(TickSliderItem):
             
         return table
             
-            
+    def isLookupTrivial(self):
+        """Return true if the gradient has exactly two stops in it: black at 0.0 and white at 1.0"""
+        ticks = self.listTicks()
+        if len(ticks) != 2:
+            return False
+        if ticks[0][1] != 0.0 or ticks[1][1] != 1.0:
+            return False
+        c1 = fn.colorTuple(ticks[0][0].color)
+        c2 = fn.colorTuple(ticks[1][0].color)
+        if c1 != (0,0,0,255) or c2 != (255,255,255,255):
+            return False
+        return True
+
 
     def mouseReleaseEvent(self, ev):
         TickSliderItem.mouseReleaseEvent(self, ev)
diff --git a/graphicsItems/HistogramLUTItem.py b/graphicsItems/HistogramLUTItem.py
index 195997205498dbd08721b2904216f7c325a58bf1..d51bbd1050fc9bde021da18fa697b983e8223b9f 100644
--- a/graphicsItems/HistogramLUTItem.py
+++ b/graphicsItems/HistogramLUTItem.py
@@ -15,17 +15,30 @@ from GridItem import *
 from pyqtgraph.Point import Point
 import pyqtgraph.functions as fn
 import numpy as np
+import pyqtgraph.debug as debug
 
 
 __all__ = ['HistogramLUTItem']
 
 
 class HistogramLUTItem(GraphicsWidget):
+    """
+    This is a graphicsWidget which provides controls for adjusting the display of an image.
+    Includes:
+       - Image histogram 
+       - Movable region over histogram to select black/white levels
+       - Gradient editor to define color lookup table for single-channel images
+    """
+    
     sigLookupTableChanged = QtCore.Signal(object)
     sigLevelsChanged = QtCore.Signal(object)
     sigLevelChangeFinished = QtCore.Signal(object)
     
-    def __init__(self, image=None):
+    def __init__(self, image=None, fillHistogram=True):
+        """
+        If *image* (ImageItem) is provided, then the control will be automatically linked to the image and changes to the control will be immediately reflected in the image's appearance.
+        By default, the histogram is rendered with a fill. For performance, set *fillHistogram* = False.
+        """
         GraphicsWidget.__init__(self)
         self.lut = None
         self.imageItem = None
@@ -61,6 +74,8 @@ class HistogramLUTItem(GraphicsWidget):
         self.vb.sigRangeChanged.connect(self.viewRangeChanged)
         self.plot = PlotDataItem()
         self.plot.rotate(90)
+        self.fillHistogram(fillHistogram)
+            
         self.vb.addItem(self.plot)
         self.autoHistogramRange()
         
@@ -68,7 +83,13 @@ class HistogramLUTItem(GraphicsWidget):
             self.setImageItem(image)
         #self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
         
-
+    def fillHistogram(self, fill=True, level=0.0, color=(100, 100, 200)):
+        if fill:
+            self.plot.setFillLevel(level)
+            self.plot.setFillBrush(color)
+        else:
+            self.plot.setFillLevel(None)
+        
     #def sizeHint(self, *args):
         #return QtCore.QSizeF(115, 200)
         
@@ -129,21 +150,24 @@ class HistogramLUTItem(GraphicsWidget):
     
     def gradientChanged(self):
         if self.imageItem is not None:
-            self.imageItem.setLookupTable(self.getLookupTable)  ## send function pointer, not the result
+            if self.gradient.isLookupTrivial():
+                self.imageItem.setLookupTable(None) #lambda x: x.astype(np.uint8))
+            else:
+                self.imageItem.setLookupTable(self.getLookupTable)  ## send function pointer, not the result
             
         self.lut = None
         #if self.imageItem is not None:
             #self.imageItem.setLookupTable(self.gradient.getLookupTable(512))
         self.sigLookupTableChanged.emit(self)
 
-    def getLookupTable(self, img=None, n=None):
+    def getLookupTable(self, img=None, n=None, alpha=False):
         if n is None:
             if img.dtype == np.uint8:
                 n = 256
             else:
                 n = 512
         if self.lut is None:
-            self.lut = self.gradient.getLookupTable(n)
+            self.lut = self.gradient.getLookupTable(n, alpha=alpha)
         return self.lut
 
     def regionChanged(self):
@@ -159,17 +183,19 @@ class HistogramLUTItem(GraphicsWidget):
         self.update()
 
     def imageChanged(self, autoLevel=False, autoRange=False):
+        prof = debug.Profiler('HistogramLUTItem.imageChanged', disabled=True)
         h = self.imageItem.getHistogram()
+        prof.mark('get histogram')
         if h[0] is None:
             return
-        self.plot.setData(*h, fillLevel=0.0, brush=(100, 100, 200))
+        self.plot.setData(*h)
+        prof.mark('set plot')
         if autoLevel:
             mn = h[0][0]
             mx = h[0][-1]
             self.region.setRegion([mn, mx])
-            #self.updateRange()
-        #if autoRange:
-            #self.updateRange()
+            prof.mark('set region')
+        prof.finish()
             
     def getLevels(self):
         return self.region.getRegion()
diff --git a/graphicsItems/ImageItem.py b/graphicsItems/ImageItem.py
index 89bd6b64a188ce9c3cd8ae04e55044f5370f8bef..423183ab003c9d815aab49a85e8667cd3811027b 100644
--- a/graphicsItems/ImageItem.py
+++ b/graphicsItems/ImageItem.py
@@ -224,10 +224,13 @@ class ImageItem(GraphicsObject):
             return
         if self.qimage is None:
             self.render()
+            prof.mark('render QImage')
         if self.paintMode is not None:
             p.setCompositionMode(self.paintMode)
+            prof.mark('set comp mode')
         
         p.drawImage(QtCore.QPointF(0,0), self.qimage)
+        prof.mark('p.drawImage')
         if self.border is not None:
             p.setPen(self.border)
             p.drawRect(self.boundingRect())
diff --git a/graphicsItems/InfiniteLine.py b/graphicsItems/InfiniteLine.py
index cffbeb52633f0e1c99837efb169f62675182078b..a886876b45b3f86d0f534a370b8f80580f0a65ae 100644
--- a/graphicsItems/InfiniteLine.py
+++ b/graphicsItems/InfiniteLine.py
@@ -35,6 +35,7 @@ class InfiniteLine(UIGraphicsItem):
             self.maxRange = bounds
         self.moving = False
         self.setMovable(movable)
+        self.mouseHovering = False
         self.p = [0, 0]
         self.setAngle(angle)
         if pos is None:
@@ -222,6 +223,16 @@ class InfiniteLine(UIGraphicsItem):
 
     def hoverEvent(self, ev):
         if (not ev.isExit()) and self.movable and ev.acceptDrags(QtCore.Qt.LeftButton):
+            self.setMouseHover(True)
+        else:
+            self.setMouseHover(False)
+
+    def setMouseHover(self, hover):
+        ## Inform the item that the mouse is(not) hovering over it
+        if self.mouseHovering == hover:
+            return
+        self.mouseHovering = hover
+        if hover:
             self.currentPen = fn.mkPen(255, 0,0)
         else:
             self.currentPen = self.pen
diff --git a/graphicsItems/LinearRegionItem.py b/graphicsItems/LinearRegionItem.py
index 1b546cb7e1cdcc7667939fd02f86ae30e48f1c16..bdffd07570a40cebc6b5bab9050d7e3f974b0649 100644
--- a/graphicsItems/LinearRegionItem.py
+++ b/graphicsItems/LinearRegionItem.py
@@ -2,6 +2,7 @@ from pyqtgraph.Qt import QtGui, QtCore
 from UIGraphicsItem import UIGraphicsItem
 from InfiniteLine import InfiniteLine
 import pyqtgraph.functions as fn
+import pyqtgraph.debug as debug
 
 __all__ = ['LinearRegionItem']
 
@@ -24,6 +25,7 @@ class LinearRegionItem(UIGraphicsItem):
         self.bounds = QtCore.QRectF()
         self.blockLineSignal = False
         self.moving = False
+        self.mouseHovering = False
         
         if orientation == LinearRegionItem.Horizontal:
             self.lines = [
@@ -94,9 +96,11 @@ class LinearRegionItem(UIGraphicsItem):
         return br.normalized()
         
     def paint(self, p, *args):
+        #prof = debug.Profiler('LinearRegionItem.paint')
         UIGraphicsItem.paint(self, p, *args)
         p.setBrush(self.currentBrush)
         p.drawRect(self.boundingRect())
+        #prof.finish()
 
     def dataBounds(self, axis, frac=1.0):
         if axis == self.orientation:
@@ -197,13 +201,23 @@ class LinearRegionItem(UIGraphicsItem):
 
     def hoverEvent(self, ev):
         if (not ev.isExit()) and ev.acceptDrags(QtCore.Qt.LeftButton):
+            self.setMouseHover(True)
+        else:
+            self.setMouseHover(False)
+            
+    def setMouseHover(self, hover):
+        ## Inform the item that the mouse is(not) hovering over it
+        if self.mouseHovering == hover:
+            return
+        self.mouseHovering = hover
+        if hover:
             c = self.brush.color()
             c.setAlpha(c.alpha() * 2)
             self.currentBrush = fn.mkBrush(c)
         else:
             self.currentBrush = self.brush
         self.update()
-            
+
     #def hoverEnterEvent(self, ev):
         #print "rgn hover enter"
         #ev.ignore()
diff --git a/graphicsItems/PlotCurveItem.py b/graphicsItems/PlotCurveItem.py
index 12ac044cb016dd1410eec4984f0be17a3cf7c25f..bc3629d20daf515918a6daf01ecd77b64aadd9ee 100644
--- a/graphicsItems/PlotCurveItem.py
+++ b/graphicsItems/PlotCurveItem.py
@@ -352,7 +352,9 @@ class PlotCurveItem(GraphicsObject):
                 p2.closeSubpath()
                 self.fillPath = p2
                 
+            prof.mark('generate fill path')
             p.fillPath(self.fillPath, self.opts['brush'])
+            prof.mark('draw fill path')
             
 
         ## Copy pens and apply alpha adjustment
diff --git a/graphicsItems/PlotDataItem.py b/graphicsItems/PlotDataItem.py
index 1938cd50851a2178c465a5a2a1270f2cf1189864..22c62d1a6540d8cc119254be4538dcb7f7f417a2 100644
--- a/graphicsItems/PlotDataItem.py
+++ b/graphicsItems/PlotDataItem.py
@@ -11,6 +11,7 @@ from ScatterPlotItem import ScatterPlotItem
 import numpy as np
 import scipy
 import pyqtgraph.functions as fn
+import pyqtgraph.debug as debug
 
 class PlotDataItem(GraphicsObject):
     """GraphicsItem for displaying plot curves, scatter plots, or both."""
@@ -215,7 +216,7 @@ class PlotDataItem(GraphicsObject):
         """
         
         #self.clear()
-        
+        prof = debug.Profiler('PlotDataItem.setData (0x%x)' % id(self), disabled=True)
         y = None
         x = None
         if len(args) == 1:
@@ -262,7 +263,7 @@ class PlotDataItem(GraphicsObject):
         if 'y' in kargs:
             y = kargs['y']
 
-
+        prof.mark('interpret data')
         ## pull in all style arguments. 
         ## Use self.opts to fill in anything not present in kargs.
         
@@ -305,12 +306,16 @@ class PlotDataItem(GraphicsObject):
         self.yData = y.view(np.ndarray)
         self.xDisp = None
         self.yDisp = None
+        prof.mark('set data')
         
         self.updateItems()
+        prof.mark('update items')
         view = self.getViewBox()
         if view is not None:
             view.itemBoundsChanged(self)  ## inform view so it can update its range if it wants
         self.sigPlotChanged.emit(self)
+        prof.mark('emit')
+        prof.finish()
 
 
     def updateItems(self):
diff --git a/graphicsItems/ROI.py b/graphicsItems/ROI.py
index a81b4c132491e4627717bc2976759be8efd2b203..5c5f930a894946dc35424c1e1ca64784386082f4 100644
--- a/graphicsItems/ROI.py
+++ b/graphicsItems/ROI.py
@@ -55,7 +55,7 @@ class ROI(GraphicsObject):
         self.rotateAllowed = True
         
         self.freeHandleMoved = False ## keep track of whether free handles have moved since last change signal was emitted.
-        
+        self.mouseHovering = False
         if pen is None:
             pen = (255, 255, 255)
         self.setPen(pen)
@@ -334,11 +334,22 @@ class ROI(GraphicsObject):
 
     def hoverEvent(self, ev):
         if self.translatable and (not ev.isExit()) and ev.acceptDrags(QtCore.Qt.LeftButton):
-            self.currentPen = fn.mkPen(255, 255, 0)
+            self.setMouseHover(True)
             self.sigHoverEvent.emit(self)
+        else:
+            self.setMouseHover(False)
+
+    def setMouseHover(self, hover):
+        ## Inform the ROI that the mouse is(not) hovering over it
+        if self.mouseHovering == hover:
+            return
+        self.mouseHovering = hover
+        if hover:
+            self.currentPen = fn.mkPen(255, 255, 0)
         else:
             self.currentPen = self.pen
         self.update()
+        
             
     def mouseDragEvent(self, ev):
         if ev.isStart():
diff --git a/widgets/GraphicsView.py b/widgets/GraphicsView.py
index 3d3be2daa1a203eaac60245eddcc2f1705dd7037..92a5d5e4135231187a4b03e8fae1bc6294175e96 100644
--- a/widgets/GraphicsView.py
+++ b/widgets/GraphicsView.py
@@ -16,6 +16,7 @@ from FileDialog import FileDialog
 from pyqtgraph.GraphicsScene import GraphicsScene
 import numpy as np
 import pyqtgraph.functions as fn
+import pyqtgraph.debug as debug
 import pyqtgraph 
 
 __all__ = ['GraphicsView']
@@ -395,6 +396,11 @@ class GraphicsView(QtGui.QGraphicsView):
             #self.pev = pev
             #self.currentItem.mouseMoveEvent(pev)
         
+    #def paintEvent(self, ev):
+        #prof = debug.Profiler('GraphicsView.paintEvent (0x%x)' % id(self))
+        #QtGui.QGraphicsView.paintEvent(self, ev)
+        #prof.finish()
+        
         
     def pixelSize(self):
         """Return vector with the length and width of one view pixel in scene coordinates"""