[Scummvm-git-logs] scummvm master -> 4d0bb753e418ee9f70937777cb3827cd3181a26b

sev- sev at scummvm.org
Mon Mar 12 11:46:08 CET 2018


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4d0bb753e4 GUI: Remove the ThemeItem draw queues


Commit: 4d0bb753e418ee9f70937777cb3827cd3181a26b
    https://github.com/scummvm/scummvm/commit/4d0bb753e418ee9f70937777cb3827cd3181a26b
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2018-03-12T11:46:04+01:00

Commit Message:
GUI: Remove the ThemeItem draw queues

Drawing nows happens directly when the Dialog or Widget draw methods are
called. This makes it easy to debug why a particular low level draw
method was called, by inspecting the call stack.

This replaces the notion of "buffering" by two independant ways to
control what is drawn and where:
- The active layer is used to select whether the foreground or
  background part of the dialogs are rendered by the draw calls.
- The active surface is used to select if the draw calls affect the back
  buffer or the screen.

The foreground layer of the active dialog is drawn directly to the
screen. Its background layer is drawn to the back buffer. This way
widgets can restore the back buffer in order to update without having to
redraw the dialog's background.

Dialogs lower in the dialog stack are drawn entirely to the back buffer.

Changed paths:
    engines/scumm/dialogs.cpp
    engines/scumm/dialogs.h
    graphics/VectorRenderer.h
    gui/EventRecorder.cpp
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h
    gui/Tooltip.cpp
    gui/Tooltip.h
    gui/about.cpp
    gui/about.h
    gui/console.cpp
    gui/console.h
    gui/dialog.cpp
    gui/dialog.h
    gui/gui-manager.cpp
    gui/massadd.cpp
    gui/widgets/popup.cpp


diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index 1af7523..215abe1 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -514,9 +514,10 @@ ValueDisplayDialog::ValueDisplayDialog(const Common::String& label, int minVal,
 	assert(_min <= _value && _value <= _max);
 }
 
-void ValueDisplayDialog::drawDialog() {
+void ValueDisplayDialog::drawDialog(GUI::DrawLayer layerToDraw) {
+	Dialog::drawDialog(layerToDraw);
+
 	const int labelWidth = _w - 8 - _percentBarWidth;
-	g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), GUI::ThemeEngine::kDialogBackgroundDefault);
 	g_gui.theme()->drawText(Common::Rect(_x+4, _y+4, _x+labelWidth+4,
 				_y+g_gui.theme()->getFontHeight()+4), _label);
 	g_gui.theme()->drawSlider(Common::Rect(_x+4+labelWidth, _y+4, _x+_w-4, _y+_h-4),
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index bd06455..9dee4c8 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -128,7 +128,7 @@ public:
 	ValueDisplayDialog(const Common::String& label, int minVal, int maxVal, int val, uint16 incKey, uint16 decKey);
 
 	virtual void open();
-	virtual void drawDialog();
+	void drawDialog(GUI::DrawLayer layerToDraw) override;
 	virtual void handleTickle();
 	virtual void handleMouseDown(int x, int y, int button, int clickCount) {
 		close();
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 5f7b6e6..2b84c21 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -290,6 +290,13 @@ public:
 	}
 
 	/**
+	 * Returns the currently active drawing surface
+	 */
+	virtual TransparentSurface *getActiveSurface() {
+		return _activeSurface;
+	}
+
+	/**
 	 * Fills the active surface with the specified fg/bg color or the active gradient.
 	 * Defaults to using the active Foreground color for filling.
 	 */
diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp
index 3981151..8494054 100644
--- a/gui/EventRecorder.cpp
+++ b/gui/EventRecorder.cpp
@@ -557,17 +557,19 @@ Common::SaveFileManager *EventRecorder::getSaveManager(Common::SaveFileManager *
 }
 
 void EventRecorder::preDrawOverlayGui() {
-    if ((_initialized) || (_needRedraw)) {
+	if ((_initialized) || (_needRedraw)) {
 		RecordMode oldMode = _recordMode;
 		_recordMode = kPassthrough;
 		g_system->showOverlay();
 		g_gui.theme()->clearAll();
-		g_gui.theme()->openDialog(true, GUI::ThemeEngine::kShadingNone);
-		_controlPanel->drawDialog();
-		g_gui.theme()->finishBuffering();
+		g_gui.theme()->drawToBackbuffer();
+		_controlPanel->drawDialog(kDrawLayerBackground);
+		g_gui.theme()->drawToScreen();
+		g_gui.theme()->copyBackBufferToScreen();
+		_controlPanel->drawDialog(kDrawLayerForeground);
 		g_gui.theme()->updateScreen();
 		_recordMode = oldMode;
-   }
+	}
 }
 
 void EventRecorder::postDrawOverlayGui() {
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index cff0947..b16a6cf 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -89,7 +89,7 @@ struct WidgetDrawData {
 	uint16 _backgroundOffset;
 	uint16 _shadowOffset;
 
-	bool _buffer;
+	DrawLayer _layer;
 
 
 	/**
@@ -102,111 +102,13 @@ struct WidgetDrawData {
 	void calcBackgroundOffset();
 };
 
-class ThemeItem {
-
-public:
-	ThemeItem(ThemeEngine *engine, const Common::Rect &area) :
-		_engine(engine), _area(area) {}
-	virtual ~ThemeItem() {}
-
-	virtual void drawSelf(bool doDraw, bool doRestore) = 0;
-
-protected:
-	ThemeEngine *_engine;
-	Common::Rect _area;
-};
-
-class ThemeItemDrawData : public ThemeItem {
-public:
-	ThemeItemDrawData(ThemeEngine *engine, const WidgetDrawData *data, const Common::Rect &area, uint32 dynData) :
-		ThemeItem(engine, area), _dynamicData(dynData), _data(data) {}
-
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	uint32 _dynamicData;
-	const WidgetDrawData *_data;
-};
-
-class ThemeItemDrawDataClip: public ThemeItem{
-public:
-	ThemeItemDrawDataClip(ThemeEngine *engine, const WidgetDrawData *data, const Common::Rect &area, const Common::Rect &clip, uint32 dynData) :
-		ThemeItem(engine, area), _dynamicData(dynData), _data(data), _clip(clip) {}
-
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	uint32 _dynamicData;
-	const WidgetDrawData *_data;
-	const Common::Rect _clip;
-};
-
-class ThemeItemTextData : public ThemeItem {
-public:
-	ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::Rect &textDrawableArea,
-	                  const Common::String &text, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
-	                  bool ellipsis, bool restoreBg, int deltaX) :
-		ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV),
-		_ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX), _textDrawableArea(textDrawableArea) {}
-
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	Common::Rect _textDrawableArea;
-	const TextDrawData *_data;
-	const TextColorData *_color;
-	Common::String _text;
-	Graphics::TextAlign _alignH;
-	GUI::ThemeEngine::TextAlignVertical _alignV;
-	bool _ellipsis;
-	bool _restoreBg;
-	int _deltax;
-};
-
-class ThemeItemBitmap : public ThemeItem {
-public:
-	ThemeItemBitmap(ThemeEngine *engine, const Common::Rect &area, const Graphics::Surface *bitmap, bool alpha) :
-		ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha) {}
-
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	const Graphics::Surface *_bitmap;
-	bool _alpha;
-};
-
-class ThemeItemABitmap : public ThemeItem {
-public:
-	ThemeItemABitmap(ThemeEngine *engine, const Common::Rect &area, Graphics::TransparentSurface *bitmap, ThemeEngine::AutoScaleMode autoscale, int alpha) :
-		ThemeItem(engine, area), _bitmap(bitmap), _autoscale(autoscale), _alpha(alpha) {}
-
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	Graphics::TransparentSurface *_bitmap;
-	ThemeEngine::AutoScaleMode _autoscale;
-	int _alpha;
-};
-
-class ThemeItemBitmapClip : public ThemeItem {
-public:
-	ThemeItemBitmapClip(ThemeEngine *engine, const Common::Rect &area, const Common::Rect &clip, const Graphics::Surface *bitmap, bool alpha) :
-		ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha), _clip(clip) {}
-	void drawSelf(bool draw, bool restore);
-
-protected:
-	const Graphics::Surface *_bitmap;
-	bool _alpha;
-	const Common::Rect _clip;
-};
-
 /**********************************************************
  *  Data definitions for theme engine elements
  *********************************************************/
 struct DrawDataInfo {
 	DrawData id;        ///< The actual ID of the DrawData item.
 	const char *name;   ///< The name of the DrawData item as it appears in the Theme Description files
-	bool buffer;        ///< Sets whether this item is buffered on the backbuffer or drawn directly to the screen.
+	DrawLayer layer;    ///< Sets whether this item is part of the foreground or background layer of its dialog
 	DrawData parent;    ///< Parent DrawData item, for items that overlay. E.g. kDDButtonIdle -> kDDButtonHover
 };
 
@@ -214,167 +116,62 @@ struct DrawDataInfo {
  * Default values for each DrawData item.
  */
 static const DrawDataInfo kDrawDataDefaults[] = {
-	{kDDMainDialogBackground,         "mainmenu_bg",          true,   kDDNone},
-	{kDDSpecialColorBackground,       "special_bg",           true,   kDDNone},
-	{kDDPlainColorBackground,         "plain_bg",             true,   kDDNone},
-	{kDDTooltipBackground,            "tooltip_bg",           true,   kDDNone},
-	{kDDDefaultBackground,            "default_bg",           true,   kDDNone},
-	{kDDTextSelectionBackground,      "text_selection",       false,  kDDNone},
-	{kDDTextSelectionFocusBackground, "text_selection_focus", false,  kDDNone},
-
-	{kDDWidgetBackgroundDefault,    "widget_default",   true,   kDDNone},
-	{kDDWidgetBackgroundSmall,      "widget_small",     true,   kDDNone},
-	{kDDWidgetBackgroundEditText,   "widget_textedit",  true,   kDDNone},
-	{kDDWidgetBackgroundSlider,     "widget_slider",    true,   kDDNone},
-
-	{kDDButtonIdle,                 "button_idle",      true,   kDDNone},
-	{kDDButtonHover,                "button_hover",     false,  kDDButtonIdle},
-	{kDDButtonDisabled,             "button_disabled",  true,   kDDNone},
-	{kDDButtonPressed,              "button_pressed",   false,  kDDButtonIdle},
-
-	{kDDSliderFull,                 "slider_full",      false,  kDDNone},
-	{kDDSliderHover,                "slider_hover",     false,  kDDNone},
-	{kDDSliderDisabled,             "slider_disabled",  false,  kDDNone},
-
-	{kDDCheckboxDefault,            "checkbox_default",         true,   kDDNone},
-	{kDDCheckboxDisabled,           "checkbox_disabled",        true,   kDDNone},
-	{kDDCheckboxSelected,           "checkbox_selected",        false,  kDDCheckboxDefault},
-
-	{kDDRadiobuttonDefault,         "radiobutton_default",      true,   kDDNone},
-	{kDDRadiobuttonDisabled,        "radiobutton_disabled",     true,   kDDNone},
-	{kDDRadiobuttonSelected,        "radiobutton_selected",     false,  kDDRadiobuttonDefault},
-
-	{kDDTabActive,                  "tab_active",               false,  kDDTabInactive},
-	{kDDTabInactive,                "tab_inactive",             true,   kDDNone},
-	{kDDTabBackground,              "tab_background",           true,   kDDNone},
-
-	{kDDScrollbarBase,              "scrollbar_base",           true,   kDDNone},
-
-	{kDDScrollbarButtonIdle,        "scrollbar_button_idle",    true,   kDDNone},
-	{kDDScrollbarButtonHover,       "scrollbar_button_hover",   false,  kDDScrollbarButtonIdle},
-
-	{kDDScrollbarHandleIdle,        "scrollbar_handle_idle",    false,  kDDNone},
-	{kDDScrollbarHandleHover,       "scrollbar_handle_hover",   false,  kDDScrollbarBase},
-
-	{kDDPopUpIdle,                  "popup_idle",       true,   kDDNone},
-	{kDDPopUpHover,                 "popup_hover",      false,  kDDPopUpIdle},
-	{kDDPopUpDisabled,              "popup_disabled",   true,   kDDNone},
-
-	{kDDCaret,                      "caret",        false,  kDDNone},
-	{kDDSeparator,                  "separator",    true,   kDDNone},
+	{kDDMainDialogBackground,         "mainmenu_bg",          kDrawLayerBackground,   kDDNone},
+	{kDDSpecialColorBackground,       "special_bg",           kDrawLayerBackground,   kDDNone},
+	{kDDPlainColorBackground,         "plain_bg",             kDrawLayerBackground,   kDDNone},
+	{kDDTooltipBackground,            "tooltip_bg",           kDrawLayerBackground,   kDDNone},
+	{kDDDefaultBackground,            "default_bg",           kDrawLayerBackground,   kDDNone},
+	{kDDTextSelectionBackground,      "text_selection",       kDrawLayerForeground,  kDDNone},
+	{kDDTextSelectionFocusBackground, "text_selection_focus", kDrawLayerForeground,  kDDNone},
+
+	{kDDWidgetBackgroundDefault,    "widget_default",   kDrawLayerBackground,   kDDNone},
+	{kDDWidgetBackgroundSmall,      "widget_small",     kDrawLayerBackground,   kDDNone},
+	{kDDWidgetBackgroundEditText,   "widget_textedit",  kDrawLayerBackground,   kDDNone},
+	{kDDWidgetBackgroundSlider,     "widget_slider",    kDrawLayerBackground,   kDDNone},
+
+	{kDDButtonIdle,                 "button_idle",      kDrawLayerBackground,   kDDNone},
+	{kDDButtonHover,                "button_hover",     kDrawLayerForeground,  kDDButtonIdle},
+	{kDDButtonDisabled,             "button_disabled",  kDrawLayerBackground,   kDDNone},
+	{kDDButtonPressed,              "button_pressed",   kDrawLayerForeground,  kDDButtonIdle},
+
+	{kDDSliderFull,                 "slider_full",      kDrawLayerForeground,  kDDNone},
+	{kDDSliderHover,                "slider_hover",     kDrawLayerForeground,  kDDNone},
+	{kDDSliderDisabled,             "slider_disabled",  kDrawLayerForeground,  kDDNone},
+
+	{kDDCheckboxDefault,            "checkbox_default",         kDrawLayerBackground,   kDDNone},
+	{kDDCheckboxDisabled,           "checkbox_disabled",        kDrawLayerBackground,   kDDNone},
+	{kDDCheckboxSelected,           "checkbox_selected",        kDrawLayerForeground,  kDDCheckboxDefault},
+
+	{kDDRadiobuttonDefault,         "radiobutton_default",      kDrawLayerBackground,   kDDNone},
+	{kDDRadiobuttonDisabled,        "radiobutton_disabled",     kDrawLayerBackground,   kDDNone},
+	{kDDRadiobuttonSelected,        "radiobutton_selected",     kDrawLayerForeground,  kDDRadiobuttonDefault},
+
+	{kDDTabActive,                  "tab_active",               kDrawLayerForeground,  kDDTabInactive},
+	{kDDTabInactive,                "tab_inactive",             kDrawLayerBackground,   kDDNone},
+	{kDDTabBackground,              "tab_background",           kDrawLayerBackground,   kDDNone},
+
+	{kDDScrollbarBase,              "scrollbar_base",           kDrawLayerBackground,   kDDNone},
+
+	{kDDScrollbarButtonIdle,        "scrollbar_button_idle",    kDrawLayerBackground,   kDDNone},
+	{kDDScrollbarButtonHover,       "scrollbar_button_hover",   kDrawLayerForeground,  kDDScrollbarButtonIdle},
+
+	{kDDScrollbarHandleIdle,        "scrollbar_handle_idle",    kDrawLayerForeground,  kDDNone},
+	{kDDScrollbarHandleHover,       "scrollbar_handle_hover",   kDrawLayerForeground,  kDDScrollbarBase},
+
+	{kDDPopUpIdle,                  "popup_idle",       kDrawLayerBackground,   kDDNone},
+	{kDDPopUpHover,                 "popup_hover",      kDrawLayerForeground,  kDDPopUpIdle},
+	{kDDPopUpDisabled,              "popup_disabled",   kDrawLayerBackground,   kDDNone},
+
+	{kDDCaret,                      "caret",        kDrawLayerForeground,  kDDNone},
+	{kDDSeparator,                  "separator",    kDrawLayerBackground,   kDDNone},
 };
 
-
-/**********************************************************
- * ThemeItem functions for drawing queues.
- *********************************************************/
-void ThemeItemDrawData::drawSelf(bool draw, bool restore) {
-
-	Common::Rect extendedRect = _area;
-	extendedRect.grow(_engine->kDirtyRectangleThreshold + _data->_backgroundOffset);
-	if (_data->_shadowOffset > _data->_backgroundOffset) {
-		extendedRect.right += _data->_shadowOffset - _data->_backgroundOffset;
-		extendedRect.bottom += _data->_shadowOffset - _data->_backgroundOffset;
-	}
-
-	if (restore)
-		_engine->restoreBackground(extendedRect);
-
-	if (draw) {
-		Common::List<Graphics::DrawStep>::const_iterator step;
-		for (step = _data->_steps.begin(); step != _data->_steps.end(); ++step)
-			_engine->renderer()->drawStep(_area, *step, _dynamicData);
-	}
-
-	_engine->addDirtyRect(extendedRect);
-}
-
-void ThemeItemDrawDataClip::drawSelf(bool draw, bool restore) {
-
-	Common::Rect extendedRect = _area;
-	extendedRect.grow(_engine->kDirtyRectangleThreshold + _data->_backgroundOffset);
-	if (_data->_shadowOffset > _data->_backgroundOffset) {
-		extendedRect.right += _data->_shadowOffset - _data->_backgroundOffset;
-		extendedRect.bottom += _data->_shadowOffset - _data->_backgroundOffset;
-	}
-
-	if (restore)
-		_engine->restoreBackground(extendedRect);
-
-	if (draw) {
-		Common::List<Graphics::DrawStep>::const_iterator step;
-		for (step = _data->_steps.begin(); step != _data->_steps.end(); ++step) {
-			_engine->renderer()->drawStepClip(_area, _clip, *step, _dynamicData);
-		}
-	}
-
-	extendedRect.clip(_clip);
-
-	_engine->addDirtyRect(extendedRect);
-}
-
-void ThemeItemTextData::drawSelf(bool draw, bool restore) {
-	Common::Rect dirty = _textDrawableArea;
-	if (dirty.isEmpty()) dirty = _area;
-	else dirty.clip(_area);
-
-	if (_restoreBg || restore)
-		_engine->restoreBackground(dirty);
-
-	if (draw) {
-		_engine->renderer()->setFgColor(_color->r, _color->g, _color->b);
-		_engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis, _textDrawableArea);
-	}
-
-	_engine->addDirtyRect(dirty);
-}
-
-void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
-	if (restore)
-		_engine->restoreBackground(_area);
-
-	if (draw) {
-		if (_alpha)
-			_engine->renderer()->blitKeyBitmap(_bitmap, _area);
-		else
-			_engine->renderer()->blitSubSurface(_bitmap, _area);
-	}
-
-	_engine->addDirtyRect(_area);
-}
-
-void ThemeItemABitmap::drawSelf(bool draw, bool restore) {
-	if (restore)
-		_engine->restoreBackground(_area);
-
-	if (draw)
-		_engine->renderer()->blitAlphaBitmap(_bitmap, _area, _autoscale, Graphics::DrawStep::kVectorAlignManual, Graphics::DrawStep::kVectorAlignManual, _alpha);
-
-	_engine->addDirtyRect(_area);
-}
-
-void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) {
-	if (restore)
-		 _engine->restoreBackground(_area);
-
-	if (draw) {
-		if (_alpha)
-			_engine->renderer()->blitKeyBitmapClip(_bitmap, _area, _clip);
-		else
-			_engine->renderer()->blitSubSurfaceClip(_bitmap, _area, _clip);
-	}
-
-	Common::Rect dirtyRect = _area;
-	dirtyRect.clip(_clip);
-	_engine->addDirtyRect(dirtyRect);
-}
-
 /**********************************************************
  * ThemeEngine class
  *********************************************************/
 ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
 	_system(0), _vectorRenderer(0),
-	_buffering(false), _bytesPerPixel(0),  _graphicsMode(kGfxDisabled),
+	_layerToDraw(kDrawLayerBackground), _bytesPerPixel(0),  _graphicsMode(kGfxDisabled),
 	_font(0), _initOk(false), _themeOk(false), _enabled(false), _themeFiles(),
 	_cursor(0) {
 
@@ -555,7 +352,7 @@ bool ThemeEngine::init() {
 void ThemeEngine::clearAll() {
 	if (_initOk) {
 		_system->clearOverlay();
-		_system->grabOverlay(_screen.getPixels(), _screen.pitch);
+		_system->grabOverlay(_backBuffer.getPixels(), _backBuffer.pitch);
 	}
 }
 
@@ -671,8 +468,15 @@ void WidgetDrawData::calcBackgroundOffset() {
 }
 
 void ThemeEngine::restoreBackground(Common::Rect r) {
+	if (_vectorRenderer->getActiveSurface() == &_backBuffer) {
+		// Only restore the background when drawing to the screen surface
+		return;
+	}
+
 	r.clip(_screen.w, _screen.h);
 	_vectorRenderer->blitSurface(&_backBuffer, r);
+
+	addDirtyRect(r);
 }
 
 
@@ -871,7 +675,7 @@ bool ThemeEngine::addDrawData(const Common::String &data, bool cached) {
 		delete _widgets[id];
 
 	_widgets[id] = new WidgetDrawData;
-	_widgets[id]->_buffer = kDrawDataDefaults[id].buffer;
+	_widgets[id]->_layer = kDrawDataDefaults[id].layer;
 	_widgets[id]->_textDataId = kTextDataNone;
 
 	return true;
@@ -1028,143 +832,167 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeId) {
 
 
 /**********************************************************
- * Drawing Queue management
+ * Draw Date descriptors drawing functions
  *********************************************************/
-void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool restore) {
-	if (_widgets[type] == 0)
+void ThemeEngine::drawDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool forceRestore) {
+	WidgetDrawData *drawData = _widgets[type];
+
+	if (!drawData)
 		return;
 
+	if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
+		drawDD(kDrawDataDefaults[type].parent, r);
+
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemDrawData *q = new ThemeItemDrawData(this, _widgets[type], area, dynamic);
+	Common::Rect extendedRect = area;
+	extendedRect.grow(kDirtyRectangleThreshold + drawData->_backgroundOffset);
+	if (drawData->_shadowOffset > drawData->_backgroundOffset) {
+		extendedRect.right += drawData->_shadowOffset - drawData->_backgroundOffset;
+		extendedRect.bottom += drawData->_shadowOffset - drawData->_backgroundOffset;
+	}
 
-	if (_buffering) {
-		if (_widgets[type]->_buffer) {
-			_bufferQueue.push_back(q);
-		} else {
-			if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
-				queueDD(kDrawDataDefaults[type].parent, r);
+	if (forceRestore || drawData->_layer == kDrawLayerBackground)
+		restoreBackground(extendedRect);
 
-			_screenQueue.push_back(q);
-		}
-	} else {
-		q->drawSelf(!_widgets[type]->_buffer, restore || _widgets[type]->_buffer);
-		delete q;
+	if (drawData->_layer == _layerToDraw) {
+		Common::List<Graphics::DrawStep>::const_iterator step;
+		for (step = drawData->_steps.begin(); step != drawData->_steps.end(); ++step)
+			_vectorRenderer->drawStep(area, *step, dynamic);
+
+		addDirtyRect(extendedRect);
 	}
 }
 
-void ThemeEngine::queueDDClip(DrawData type, const Common::Rect &r, const Common::Rect &clippingRect, uint32 dynamic, bool restore) {
-	if (_widgets[type] == 0)
+void ThemeEngine::drawDDClip(DrawData type, const Common::Rect &r, const Common::Rect &clippingRect, uint32 dynamic,
+                             bool forceRestore) {
+	WidgetDrawData *drawData = _widgets[type];
+
+	if (!drawData)
 		return;
 
+	if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
+		drawDDClip(kDrawDataDefaults[type].parent, r, clippingRect);
+
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemDrawDataClip *q = new ThemeItemDrawDataClip(this, _widgets[type], area, clippingRect, dynamic);
+	Common::Rect extendedRect = area;
+	extendedRect.grow(kDirtyRectangleThreshold + drawData->_backgroundOffset);
+	if (drawData->_shadowOffset > drawData->_backgroundOffset) {
+		extendedRect.right += drawData->_shadowOffset - drawData->_backgroundOffset;
+		extendedRect.bottom += drawData->_shadowOffset - drawData->_backgroundOffset;
+	}
+	extendedRect.clip(clippingRect);
 
-	if (_buffering) {
-		if (_widgets[type]->_buffer) {
-			_bufferQueue.push_back(q);
-		} else {
-			if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
-				queueDDClip(kDrawDataDefaults[type].parent, r, clippingRect);
+	if (forceRestore || drawData->_layer == kDrawLayerBackground)
+		restoreBackground(extendedRect);
 
-			_screenQueue.push_back(q);
+	if (drawData->_layer == _layerToDraw) {
+		Common::List<Graphics::DrawStep>::const_iterator step;
+		for (step = drawData->_steps.begin(); step != drawData->_steps.end(); ++step) {
+			_vectorRenderer->drawStepClip(area, clippingRect, *step, dynamic);
 		}
-	} else {
-		q->drawSelf(!_widgets[type]->_buffer, restore || _widgets[type]->_buffer);
-		delete q;
+
+		addDirtyRect(extendedRect);
 	}
 }
 
-void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
-                              bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax, const Common::Rect &drawableTextArea) {
+void ThemeEngine::drawDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text,
+                             bool restoreBg, bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV,
+                             int deltax, const Common::Rect &drawableTextArea) {
 
-	if (type == kTextDataNone || _texts[type] == 0)
+	if (type == kTextDataNone || !_texts[type] || _layerToDraw == kDrawLayerBackground)
 		return;
 
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, drawableTextArea, text, alignH, alignV, ellipsis, restoreBg, deltax);
+	Common::Rect dirty = drawableTextArea;
+	if (dirty.isEmpty()) dirty = area;
+	else dirty.clip(area);
 
-	if (_buffering) {
-		_screenQueue.push_back(q);
-	} else {
-		q->drawSelf(true, false);
-		delete q;
-	}
+	if (restoreBg)
+		restoreBackground(dirty);
+
+	_vectorRenderer->setFgColor(_textColors[color]->r, _textColors[color]->g, _textColors[color]->b);
+	_vectorRenderer->drawString(_texts[type]->_fontPtr, text, area, alignH, alignV, deltax, ellipsis, drawableTextArea);
+
+	addDirtyRect(dirty);
 }
 
-void ThemeEngine::queueDDTextClip(TextData type, TextColor color, const Common::Rect &r, const Common::Rect &clippingArea, const Common::String &text, bool restoreBg,
-	bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax, const Common::Rect &drawableTextArea) {
+void ThemeEngine::drawDDTextClip(TextData type, TextColor color, const Common::Rect &r,
+                                 const Common::Rect &clippingArea, const Common::String &text, bool restoreBg,
+                                 bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax,
+                                 const Common::Rect &drawableTextArea) {
 
-	if (_texts[type] == 0)
+	if (type == kTextDataNone || !_texts[type] || _layerToDraw == kDrawLayerBackground)
 		return;
 
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
-	Common::Rect textArea = drawableTextArea;
-	if (textArea.isEmpty()) textArea = clippingArea;
-	else {
-		textArea.clip(clippingArea);
-		if (textArea.isEmpty()) textArea = Common::Rect(0, 0, 1, 1); // one small pixel should be invisible enough
-	}
 
-	ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, textArea, text, alignH, alignV, ellipsis, restoreBg, deltax);
+	Common::Rect dirty = drawableTextArea;
+	if (dirty.isEmpty()) dirty = area;
+	else dirty.clip(area);
 
-	if (_buffering) {
-		_screenQueue.push_back(q);
-	} else {
-		q->drawSelf(true, false);
-		delete q;
-	}
+	dirty.clip(clippingArea);
+
+	// HACK: One small pixel should be invisible enough
+	if (dirty.isEmpty()) dirty = Common::Rect(0, 0, 1, 1);
+
+	if (restoreBg)
+		restoreBackground(dirty);
+
+	_vectorRenderer->setFgColor(_textColors[color]->r, _textColors[color]->g, _textColors[color]->b);
+	_vectorRenderer->drawString(_texts[type]->_fontPtr, text, area, alignH, alignV, deltax, ellipsis, dirty);
+
+	addDirtyRect(dirty);
 }
 
-void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) {
+void ThemeEngine::drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) {
+	if (_layerToDraw == kDrawLayerBackground)
+		return;
 
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha);
+	if (alpha)
+		_vectorRenderer->blitKeyBitmap(bitmap, r);
+	else
+		_vectorRenderer->blitSubSurface(bitmap, r);
 
-	if (_buffering) {
-		_screenQueue.push_back(q);
-	} else {
-		q->drawSelf(true, false);
-		delete q;
-	}
+	addDirtyRect(r);
 }
 
-void ThemeEngine::queueABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha) {
+void ThemeEngine::drawABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha) {
+	if (_layerToDraw == kDrawLayerBackground)
+		return;
 
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemABitmap *q = new ThemeItemABitmap(this, area, bitmap, autoscale, alpha);
+	_vectorRenderer->blitAlphaBitmap(bitmap, area, autoscale, Graphics::DrawStep::kVectorAlignManual, Graphics::DrawStep::kVectorAlignManual, alpha);
 
-	if (_buffering) {
-		_screenQueue.push_back(q);
-	} else {
-		q->drawSelf(true, false);
-		delete q;
-	}
+	addDirtyRect(area);
 }
 
-void ThemeEngine::queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &r, const Common::Rect &clip, bool alpha) {
+void ThemeEngine::drawBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &r, const Common::Rect &clip, bool alpha) {
+	if (_layerToDraw == kDrawLayerBackground)
+		return;
 
 	Common::Rect area = r;
 	area.clip(_screen.w, _screen.h);
 
-	ThemeItemBitmapClip *q = new ThemeItemBitmapClip(this, area, clip, bitmap, alpha);
+	if (alpha)
+		_vectorRenderer->blitKeyBitmapClip(bitmap, area, clip);
+	else
+		_vectorRenderer->blitSubSurfaceClip(bitmap, area, clip);
 
-	if (_buffering) {
-		_screenQueue.push_back(q);
-	} else {
-		q->drawSelf(true, false);
-		delete q;
-	}
+	Common::Rect dirtyRect = area;
+	dirtyRect.clip(clip);
+	addDirtyRect(dirtyRect);
 }
 
 /**********************************************************
@@ -1185,8 +1013,8 @@ void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, W
 	else if (state == kStatePressed)
 		dd = kDDButtonPressed;
 
-	queueDD(dd, r, 0, hints & WIDGET_CLEARBG);
-	queueDDText(getTextData(dd), getTextColor(dd), r, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDD(dd, r, 0, hints & WIDGET_CLEARBG);
+	drawDDText(getTextData(dd), getTextColor(dd), r, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawButtonClip(const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &str, WidgetStateInfo state, uint16 hints) {
@@ -1204,22 +1032,22 @@ void ThemeEngine::drawButtonClip(const Common::Rect &r, const Common::Rect &clip
 	else if (state == kStatePressed)
 		dd = kDDButtonPressed;
 
-	queueDDClip(dd, r, clippingRect, 0, hints & WIDGET_CLEARBG);
-	queueDDTextClip(getTextData(dd), getTextColor(dd), r, clippingRect, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDDClip(dd, r, clippingRect, 0, hints & WIDGET_CLEARBG);
+	drawDDTextClip(getTextData(dd), getTextColor(dd), r, clippingRect, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) {
 	if (!ready())
 		return;
 
-	queueDD(kDDSeparator, r);
+	drawDD(kDDSeparator, r);
 }
 
 void ThemeEngine::drawLineSeparatorClip(const Common::Rect &r, const Common::Rect &clippingRect, WidgetStateInfo state) {
 	if (!ready())
 		return;
 
-	queueDDClip(kDDSeparator, r, clippingRect);
+	drawDDClip(kDDSeparator, r, clippingRect);
 }
 
 void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -1240,12 +1068,12 @@ void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str,
 	r2.bottom = r2.top + checkBoxSize;
 	r2.right = r2.left + checkBoxSize;
 
-	queueDD(dd, r2);
+	drawDD(dd, r2);
 
 	r2.left = r2.right + checkBoxSize;
 	r2.right = r.right;
 
-	queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawCheckboxClip(const Common::Rect &r, const Common::Rect &clip, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -1266,12 +1094,12 @@ void ThemeEngine::drawCheckboxClip(const Common::Rect &r, const Common::Rect &cl
 	r2.bottom = r2.top + checkBoxSize;
 	r2.right = r2.left + checkBoxSize;
 
-	queueDDClip(dd, r2, clip);
+	drawDDClip(dd, r2, clip);
 
 	r2.left = r2.right + checkBoxSize;
 	r2.right = r.right;
 
-	queueDDTextClip(getTextData(dd), getTextColor(dd), r2, clip, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDDTextClip(getTextData(dd), getTextColor(dd), r2, clip, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -1292,12 +1120,12 @@ void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &s
 	r2.bottom = r2.top + checkBoxSize;
 	r2.right = r2.left + checkBoxSize;
 
-	queueDD(dd, r2);
+	drawDD(dd, r2);
 
 	r2.left = r2.right + checkBoxSize;
 	r2.right = r.right;
 
-	queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawRadiobuttonClip(const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -1318,12 +1146,12 @@ void ThemeEngine::drawRadiobuttonClip(const Common::Rect &r, const Common::Rect
 	r2.bottom = r2.top + checkBoxSize;
 	r2.right = r2.left + checkBoxSize;
 
-	queueDDClip(dd, r2, clippingRect);
+	drawDDClip(dd, r2, clippingRect);
 
 	r2.left = r2.right + checkBoxSize;
 	r2.right = MAX(r2.left, r.right);
 
-	queueDDTextClip(getTextData(dd), getTextColor(dd), r2, clippingRect, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+	drawDDTextClip(getTextData(dd), getTextColor(dd), r2, clippingRect, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
 }
 
 void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
@@ -1343,7 +1171,7 @@ void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo s
 
 	drawWidgetBackground(r, 0, kWidgetBackgroundSlider, kStateEnabled);
 
-	queueDD(dd, r2);
+	drawDD(dd, r2);
 }
 
 void ThemeEngine::drawSliderClip(const Common::Rect &r, const Common::Rect &clip, int width, WidgetStateInfo state) {
@@ -1363,23 +1191,23 @@ void ThemeEngine::drawSliderClip(const Common::Rect &r, const Common::Rect &clip
 
 	drawWidgetBackgroundClip(r, clip, 0, kWidgetBackgroundSlider, kStateEnabled);
 
-	queueDDClip(dd, r2, clip);
+	drawDDClip(dd, r2, clip);
 }
 
 void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState scrollState, WidgetStateInfo state) {
 	if (!ready())
 		return;
 
-	queueDD(kDDScrollbarBase, r);
+	drawDD(kDDScrollbarBase, r);
 
 	Common::Rect r2 = r;
 	const int buttonExtra = (r.width() * 120) / 100;
 
 	r2.bottom = r2.top + buttonExtra;
-	queueDD(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleUp);
+	drawDD(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleUp);
 
 	r2.translate(0, r.height() - r2.height());
-	queueDD(scrollState == kScrollbarStateDown ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleDown);
+	drawDD(scrollState == kScrollbarStateDown ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleDown);
 
 	r2 = r;
 	r2.left += 1;
@@ -1389,30 +1217,30 @@ void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHe
 
 	//r2.top += r.width() / 5;
 	//r2.bottom -= r.width() / 5;
-	queueDD(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2);
+	drawDD(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2);
 }
 
 void ThemeEngine::drawScrollbarClip(const Common::Rect &r, const Common::Rect &clippingRect, int sliderY, int sliderHeight, ScrollbarState scrollState, WidgetStateInfo state) {
 	if (!ready())
 		return;
 
-	queueDDClip(kDDScrollbarBase, r, clippingRect);
+	drawDDClip(kDDScrollbarBase, r, clippingRect);
 
 	Common::Rect r2 = r;
 	const int buttonExtra = (r.width() * 120) / 100;
 
 	r2.bottom = r2.top + buttonExtra;
-	queueDDClip(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, clippingRect, Graphics::VectorRenderer::kTriangleUp);
+	drawDDClip(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, clippingRect, Graphics::VectorRenderer::kTriangleUp);
 
 	r2.translate(0, r.height() - r2.height());
-	queueDDClip(scrollState == kScrollbarStateDown ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, clippingRect, Graphics::VectorRenderer::kTriangleDown);
+	drawDDClip(scrollState == kScrollbarStateDown ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, clippingRect, Graphics::VectorRenderer::kTriangleDown);
 
 	r2 = r;
 	r2.left += 1;
 	r2.right -= 1;
 	r2.top += sliderY;
 	r2.bottom = r2.top + sliderHeight;
-	queueDDClip(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2, clippingRect);
+	drawDDClip(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2, clippingRect);
 }
 
 void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground bgtype, WidgetStateInfo state) {
@@ -1421,23 +1249,23 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b
 
 	switch (bgtype) {
 	case kDialogBackgroundMain:
-		queueDD(kDDMainDialogBackground, r);
+		drawDD(kDDMainDialogBackground, r);
 		break;
 
 	case kDialogBackgroundSpecial:
-		queueDD(kDDSpecialColorBackground, r);
+		drawDD(kDDSpecialColorBackground, r);
 		break;
 
 	case kDialogBackgroundPlain:
-		queueDD(kDDPlainColorBackground, r);
+		drawDD(kDDPlainColorBackground, r);
 		break;
 
 	case kDialogBackgroundTooltip:
-		queueDD(kDDTooltipBackground, r);
+		drawDD(kDDTooltipBackground, r);
 		break;
 
 	case kDialogBackgroundDefault:
-		queueDD(kDDDefaultBackground, r);
+		drawDD(kDDDefaultBackground, r);
 		break;
 	case kDialogBackgroundNone:
 		break;
@@ -1450,23 +1278,23 @@ void ThemeEngine::drawDialogBackgroundClip(const Common::Rect &r, const Common::
 
 	switch (bgtype) {
 	case kDialogBackgroundMain:
-		queueDDClip(kDDMainDialogBackground, r, clip);
+		drawDDClip(kDDMainDialogBackground, r, clip);
 		break;
 
 	case kDialogBackgroundSpecial:
-		queueDDClip(kDDSpecialColorBackground, r, clip);
+		drawDDClip(kDDSpecialColorBackground, r, clip);
 		break;
 
 	case kDialogBackgroundPlain:
-		queueDDClip(kDDPlainColorBackground, r, clip);
+		drawDDClip(kDDPlainColorBackground, r, clip);
 		break;
 
 	case kDialogBackgroundTooltip:
-		queueDDClip(kDDTooltipBackground, r, clip);
+		drawDDClip(kDDTooltipBackground, r, clip);
 		break;
 
 	case kDialogBackgroundDefault:
-		queueDDClip(kDDDefaultBackground, r, clip);
+		drawDDClip(kDDDefaultBackground, r, clip);
 		break;
 	case kDialogBackgroundNone:
 		// no op
@@ -1480,9 +1308,8 @@ void ThemeEngine::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo s
 
 	if (erase) {
 		restoreBackground(r);
-		addDirtyRect(r);
 	} else
-		queueDD(kDDCaret, r);
+		drawDD(kDDCaret, r);
 }
 
 void ThemeEngine::drawCaretClip(const Common::Rect &r, const Common::Rect &clip, bool erase, WidgetStateInfo state) {
@@ -1491,9 +1318,8 @@ void ThemeEngine::drawCaretClip(const Common::Rect &r, const Common::Rect &clip,
 
 	if (erase) {
 		restoreBackground(r);
-		addDirtyRect(r);
 	} else
-		queueDDClip(kDDCaret, r, clip);
+		drawDDClip(kDDCaret, r, clip);
 }
 
 void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, Graphics::TextAlign align) {
@@ -1509,11 +1335,11 @@ void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &s
 	else if (state == kStateDisabled)
 		dd = kDDPopUpDisabled;
 
-	queueDD(dd, r);
+	drawDD(dd, r);
 
 	if (!sel.empty()) {
 		Common::Rect text(r.left + 3, r.top + 1, r.right - 10, r.bottom);
-		queueDDText(getTextData(dd), getTextColor(dd), text, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
+		drawDDText(getTextData(dd), getTextColor(dd), text, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
 	}
 }
 
@@ -1530,11 +1356,11 @@ void ThemeEngine::drawPopUpWidgetClip(const Common::Rect &r, const Common::Rect
 	else if (state == kStateDisabled)
 		dd = kDDPopUpDisabled;
 
-	queueDDClip(dd, r, clip);
+	drawDDClip(dd, r, clip);
 
 	if (!sel.empty() && r.width() >= 13 && r.height() >= 1) {
 		Common::Rect text(r.left + 3, r.top + 1, r.right - 10, r.bottom);
-		queueDDTextClip(getTextData(dd), getTextColor(dd), text, clip, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
+		drawDDTextClip(getTextData(dd), getTextColor(dd), text, clip, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
 	}
 }
 
@@ -1542,21 +1368,21 @@ void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &su
 	if (!ready())
 		return;
 
-	queueBitmap(&surface, r, themeTrans);
+	drawBitmap(&surface, r, themeTrans);
 }
 
 void ThemeEngine::drawASurface(const Common::Rect &r, Graphics::TransparentSurface &surface, AutoScaleMode autoscale, int alpha) {
 	if (!ready())
 		return;
 
-	queueABitmap(&surface, r, autoscale, alpha);
+	drawABitmap(&surface, r, autoscale, alpha);
 }
 
 void ThemeEngine::drawSurfaceClip(const Common::Rect &r, const Common::Rect &clip, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) {
 	if (!ready())
 		return;
 
-	queueBitmapClip(&surface, r, clip, themeTrans);
+	drawBitmapClip(&surface, r, clip, themeTrans);
 }
 
 void ThemeEngine::drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background, WidgetStateInfo state) {
@@ -1565,19 +1391,19 @@ void ThemeEngine::drawWidgetBackground(const Common::Rect &r, uint16 hints, Widg
 
 	switch (background) {
 	case kWidgetBackgroundBorderSmall:
-		queueDD(kDDWidgetBackgroundSmall, r);
+		drawDD(kDDWidgetBackgroundSmall, r);
 		break;
 
 	case kWidgetBackgroundEditText:
-		queueDD(kDDWidgetBackgroundEditText, r);
+		drawDD(kDDWidgetBackgroundEditText, r);
 		break;
 
 	case kWidgetBackgroundSlider:
-		queueDD(kDDWidgetBackgroundSlider, r);
+		drawDD(kDDWidgetBackgroundSlider, r);
 		break;
 
 	default:
-		queueDD(kDDWidgetBackgroundDefault, r);
+		drawDD(kDDWidgetBackgroundDefault, r);
 		break;
 	}
 }
@@ -1588,19 +1414,19 @@ void ThemeEngine::drawWidgetBackgroundClip(const Common::Rect &r, const Common::
 
 	switch (background) {
 	case kWidgetBackgroundBorderSmall:
-		queueDDClip(kDDWidgetBackgroundSmall, r, clip);
+		drawDDClip(kDDWidgetBackgroundSmall, r, clip);
 		break;
 
 	case kWidgetBackgroundEditText:
-		queueDDClip(kDDWidgetBackgroundEditText, r, clip);
+		drawDDClip(kDDWidgetBackgroundEditText, r, clip);
 		break;
 
 	case kWidgetBackgroundSlider:
-		queueDDClip(kDDWidgetBackgroundSlider, r, clip);
+		drawDDClip(kDDWidgetBackgroundSlider, r, clip);
 		break;
 
 	default:
-		queueDDClip(kDDWidgetBackgroundDefault, r, clip);
+		drawDDClip(kDDWidgetBackgroundDefault, r, clip);
 		break;
 	}
 }
@@ -1609,7 +1435,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
 	if (!ready())
 		return;
 
-	queueDD(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight));
+	drawDD(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight));
 
 	for (int i = 0; i < (int)tabs.size(); ++i) {
 		if (i == active)
@@ -1619,8 +1445,8 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
 			continue;
 
 		Common::Rect tabRect(r.left + i * tabWidth, r.top, r.left + (i + 1) * tabWidth, r.top + tabHeight);
-		queueDD(kDDTabInactive, tabRect);
-		queueDDText(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
+		drawDD(kDDTabInactive, tabRect);
+		drawDDText(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
 	}
 
 	if (active >= 0 &&
@@ -1628,8 +1454,8 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
 		Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight);
 		const uint16 tabLeft = active * tabWidth;
 		const uint16 tabRight =  MAX(r.right - tabRect.right, 0);
-		queueDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF));
-		queueDDText(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
+		drawDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF));
+		drawDDText(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
 	}
 }
 
@@ -1639,7 +1465,7 @@ void ThemeEngine::drawTabClip(const Common::Rect &r, const Common::Rect &clip, i
 
 	assert(tabs.size() == tabWidths.size());
 
-	queueDDClip(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight), clip);
+	drawDDClip(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight), clip);
 
 	int width = 0;
 	int activePos = -1;
@@ -1654,16 +1480,16 @@ void ThemeEngine::drawTabClip(const Common::Rect &r, const Common::Rect &clip, i
 
 
 		Common::Rect tabRect(r.left + width, r.top, r.left + width + tabWidths[i], r.top + tabHeight);
-		queueDDClip(kDDTabInactive, tabRect, clip);
-		queueDDTextClip(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, clip, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
+		drawDDClip(kDDTabInactive, tabRect, clip);
+		drawDDTextClip(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, clip, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
 	}
 
 	if (activePos >= 0) {
 		Common::Rect tabRect(r.left + activePos, r.top, r.left + activePos + tabWidths[active], r.top + tabHeight);
 		const uint16 tabLeft = activePos;
 		const uint16 tabRight = MAX(r.right - tabRect.right, 0);
-		queueDDClip(kDDTabActive, tabRect, clip, (tabLeft << 16) | (tabRight & 0xFFFF));
-		queueDDTextClip(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, clip, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
+		drawDDClip(kDDTabActive, tabRect, clip, (tabLeft << 16) | (tabRight & 0xFFFF));
+		drawDDTextClip(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, clip, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
 	}
 }
 
@@ -1724,12 +1550,12 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
 
 	switch (inverted) {
 	case kTextInversion:
-		queueDD(kDDTextSelectionBackground, r);
+		drawDD(kDDTextSelectionBackground, r);
 		restore = false;
 		break;
 
 	case kTextInversionFocus:
-		queueDD(kDDTextSelectionFocusBackground, r);
+		drawDD(kDDTextSelectionFocusBackground, r);
 		restore = false;
 		break;
 
@@ -1737,7 +1563,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
 		break;
 	}
 
-	queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
+	drawDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
 }
 
 void ThemeEngine::drawTextClip(const Common::Rect &r, const Common::Rect &clippingArea, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore, const Common::Rect &drawableTextArea) {
@@ -1797,12 +1623,12 @@ void ThemeEngine::drawTextClip(const Common::Rect &r, const Common::Rect &clippi
 
 	switch (inverted) {
 	case kTextInversion:
-		queueDDClip(kDDTextSelectionBackground, r, clippingArea);
+		drawDDClip(kDDTextSelectionBackground, r, clippingArea);
 		restore = false;
 		break;
 
 	case kTextInversionFocus:
-		queueDDClip(kDDTextSelectionFocusBackground, r, clippingArea);
+		drawDDClip(kDDTextSelectionFocusBackground, r, clippingArea);
 		restore = false;
 		break;
 
@@ -1810,7 +1636,7 @@ void ThemeEngine::drawTextClip(const Common::Rect &r, const Common::Rect &clippi
 		break;
 	}
 
-	queueDDTextClip(textId, colorId, r, clippingArea, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
+	drawDDTextClip(textId, colorId, r, clippingArea, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
 }
 
 void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) {
@@ -1853,40 +1679,18 @@ void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) {
 /**********************************************************
  * Screen/overlay management
  *********************************************************/
-void ThemeEngine::updateScreen(bool render) {
-	if (!_bufferQueue.empty()) {
-		_vectorRenderer->setSurface(&_backBuffer);
-
-		for (Common::List<ThemeItem *>::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) {
-			(*q)->drawSelf(true, false);
-			delete *q;
-		}
-
-		_vectorRenderer->setSurface(&_screen);
-		memcpy(_screen.getPixels(), _backBuffer.getPixels(), _screen.pitch * _screen.h);
-		_bufferQueue.clear();
-	}
-
-	if (!_screenQueue.empty()) {
-		_vectorRenderer->disableShadows();
-		for (Common::List<ThemeItem *>::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) {
-			(*q)->drawSelf(true, false);
-			delete *q;
-		}
-
-		_vectorRenderer->enableShadows();
-		_screenQueue.clear();
-	}
+void ThemeEngine::copyBackBufferToScreen() {
+	memcpy(_screen.getPixels(), _backBuffer.getPixels(), _screen.pitch * _screen.h);
+}
 
-	if (render) {
+void ThemeEngine::updateScreen() {
 #ifdef LAYOUT_DEBUG_DIALOG
-		_vectorRenderer->fillSurface();
-		_themeEval->debugDraw(&_screen, _font);
-		_vectorRenderer->copyWholeFrame(_system);
+	_vectorRenderer->fillSurface();
+	_themeEval->debugDraw(&_screen, _font);
+	_vectorRenderer->copyWholeFrame(_system);
 #else
-		renderDirtyScreen();
+	updateDirtyScreen();
 #endif
-	}
 }
 
 void ThemeEngine::addDirtyRect(Common::Rect r) {
@@ -1917,7 +1721,7 @@ void ThemeEngine::addDirtyRect(Common::Rect r) {
 	_dirtyScreen.push_back(r);
 }
 
-void ThemeEngine::renderDirtyScreen() {
+void ThemeEngine::updateDirtyScreen() {
 	if (_dirtyScreen.empty())
 		return;
 
@@ -1929,17 +1733,11 @@ void ThemeEngine::renderDirtyScreen() {
 	_dirtyScreen.clear();
 }
 
-void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
-	if (doBuffer)
-		_buffering = true;
-
+void ThemeEngine::applyScreenShading(ShadingStyle style) {
 	if (style != kShadingNone) {
 		_vectorRenderer->applyScreenShading(style);
 		addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h));
 	}
-
-	memcpy(_backBuffer.getPixels(), _screen.getPixels(), _screen.pitch * _screen.h);
-	_vectorRenderer->setSurface(&_screen);
 }
 
 bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY) {
@@ -2476,5 +2274,12 @@ void ThemeEngine::hideCursor() {
 	}
 }
 
+void ThemeEngine::drawToBackbuffer() {
+	_vectorRenderer->setSurface(&_backBuffer);
+}
+
+void ThemeEngine::drawToScreen() {
+	_vectorRenderer->setSurface(&_screen);
+}
 
 } // End of namespace GUI.
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 9d8ed41..5675f0c 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -54,7 +54,6 @@ struct TextColorData;
 class Dialog;
 class GuiObject;
 class ThemeEval;
-class ThemeItem;
 class ThemeParser;
 
 /**
@@ -113,6 +112,18 @@ enum DrawData {
 	kDDNone = -1
 };
 
+/**
+ * Dialog layers.
+ * The currently active dialog has two layers, background and foreground.
+ * The background layer is drawn to the backbuffer. The foreground layer
+ * is drawn to the screen. This allows draw calls to restore the background
+ * layer before redrawing a widget.
+ */
+enum DrawLayer {
+	kDrawLayerBackground,
+	kDrawLayerForeground
+};
+
 // FIXME: TextData is really a bad name, not conveying what this enum is about.
 enum TextData {
 	kTextDataNone = -1,
@@ -308,22 +319,38 @@ public:
 	const Graphics::PixelFormat getPixelFormat() const { return _overlayFormat; }
 
 	/**
-	 * Implementation of the GUI::Theme API. Called when a
-	 * new dialog is opened. Note that the boolean parameter
-	 * meaning has been changed.
+	 * Draw full screen shading with the supplied style
+	 *
+	 * This is used to dim the inactive dialogs so the active one stands out.
+	 */
+	void applyScreenShading(ShadingStyle shading);
+
+	/**
+	 * Sets the active drawing surface to the back buffer.
+	 *
+	 * All drawing from this point on will be done on that surface.
+	 * The back buffer surface needs to be copied to the screen surface
+	 * in order to become visible.
+	 */
+	void drawToBackbuffer();
+
+	/**
+	 * Sets the active drawing surface to the screen.
 	 *
-	 * @param enableBuffering If set to true, buffering is enabled for
-	 *                        drawing this dialog, and will continue enabled
-	 *                        until disabled.
+	 * All drawing from this point on will be done on that surface.
 	 */
-	void openDialog(bool enableBuffering, ShadingStyle shading = kShadingNone);
+	void drawToScreen();
 
 	/**
 	 * The updateScreen() method is called every frame.
-	 * It processes all the drawing queues and then copies dirty rects
-	 * in the current Screen surface to the overlay.
+	 * It copies dirty rectangles in the Screen surface to the overlay.
 	 */
-	void updateScreen(bool render = true);
+	void updateScreen();
+
+	/**
+	 * Copy the entire backbuffer surface to the screen surface
+	 */
+	void copyBackBufferToScreen();
 
 
 	/** @name FONT MANAGEMENT METHODS */
@@ -425,8 +452,8 @@ public:
 
 	/**
 	 * Actual implementation of a dirty rect handling.
-	 * Dirty rectangles are queued on a list and are later used for the
-	 * actual drawing.
+	 * Dirty rectangles are queued on a list, merged and optimized
+	 * when possible and are later used for the actual drawing.
 	 *
 	 * @param r Area of the dirty rect.
 	 */
@@ -534,13 +561,6 @@ protected:
 	void setGraphicsMode(GraphicsMode mode);
 
 public:
-	/**
-	 * Finishes buffering: widgets from then on will be drawn straight on the screen
-	 * without drawing queues.
-	 */
-	inline void finishBuffering() { _buffering = false; }
-	inline void startBuffering() { _buffering = true; }
-
 	inline ThemeEval *getEvaluator() { return _themeEval; }
 	inline Graphics::VectorRenderer *renderer() { return _vectorRenderer; }
 
@@ -623,33 +643,35 @@ protected:
 	const Graphics::Font *loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont);
 
 	/**
-	 * Actual Dirty Screen handling function.
-	 * Handles all the dirty squares in the list, merges and optimizes
-	 * them when possible and draws them to the screen.
-	 * Called from updateScreen()
+	 * Dirty Screen handling function.
+	 * Draws all the dirty rectangles in the list to the overlay.
 	 */
-	void renderDirtyScreen();
+	void updateDirtyScreen();
 
 	/**
-	 * Generates a DrawQueue item and enqueues it so it's drawn to the screen
-	 * when the drawing queue is processed.
+	 * Draws a GUI element according to a DrawData descriptor.
 	 *
-	 * If Buffering is enabled, the DrawQueue item will be automatically placed
-	 * on its corresponding queue.
-	 * If Buffering is disabled, the DrawQueue item will be processed immediately
-	 * and drawn to the screen.
+	 * Only calls with a DrawData layer attribute matching the active layer
+	 * are actually drawn to the active surface.
 	 *
-	 * This function is called from all the Widget Drawing methods.
+	 * These functions are called from all the Widget drawing methods.
 	 */
-	void queueDD(DrawData type,  const Common::Rect &r, uint32 dynamic = 0, bool restore = false);
-	void queueDDClip(DrawData type, const Common::Rect &r, const Common::Rect &clippingRect, uint32 dynamic = 0, bool restore = false);
-	void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
-	                 bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
-	void queueDDTextClip(TextData type, TextColor color, const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &text, bool restoreBg,
-					 bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
-	void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
-	void queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, const Common::Rect &r, bool alpha);
-	void queueABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha);
+	void drawDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool forceRestore = false);
+	void drawDDClip(DrawData type, const Common::Rect &r, const Common::Rect &clippingRect, uint32 dynamic = 0,
+	                bool forceRestore = false);
+	void drawDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
+	                bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
+	                TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
+	                const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
+	void drawDDTextClip(TextData type, TextColor color, const Common::Rect &r, const Common::Rect &clippingRect,
+	                    const Common::String &text, bool restoreBg,
+	                    bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
+	                    TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
+	                    const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
+	void drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
+	void drawBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, const Common::Rect &r,
+	                    bool alpha);
+	void drawABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha);
 
 	/**
 	 * DEBUG: Draws a white square and writes some text next to it.
@@ -695,9 +717,13 @@ protected:
 	/** Backbuffer surface. Stores previous states of the screen to blit back */
 	Graphics::TransparentSurface _backBuffer;
 
-	/** Sets whether the current drawing is being buffered (stored for later
-	    processing) or drawn directly to the screen. */
-	bool _buffering;
+	/**
+	 * Filter the submitted DrawData descriptors according to their layer attribute
+	 *
+	 * This is used to selectively draw the background or foreground layer
+	 * of the dialogs.
+	 */
+	DrawLayer _layerToDraw;
 
 	/** Bytes per pixel of the Active Drawing Surface (i.e. the screen) */
 	int _bytesPerPixel;
@@ -731,12 +757,6 @@ protected:
 	/** List of all the dirty screens that must be blitted to the overlay. */
 	Common::List<Common::Rect> _dirtyScreen;
 
-	/** Queue with all the drawing that must be done to the Back Buffer */
-	Common::List<ThemeItem *> _bufferQueue;
-
-	/** Queue with all the drawing that must be done to the screen */
-	Common::List<ThemeItem *> _screenQueue;
-
 	bool _initOk;  ///< Class and renderer properly initialized
 	bool _themeOk; ///< Theme data successfully loaded.
 	bool _enabled; ///< Whether the Theme is currently shown on the overlay
diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp
index 09ad7ce..bcaa8ce 100644
--- a/gui/Tooltip.cpp
+++ b/gui/Tooltip.cpp
@@ -56,11 +56,11 @@ void Tooltip::setup(Dialog *parent, Widget *widget, int x, int y) {
 	_y = MIN<int16>(parent->_y + y + _ydelta, g_gui.getHeight() - _h - 3);
 }
 
-void Tooltip::drawDialog() {
+void Tooltip::drawDialog(DrawLayer layerToDraw) {
 	int num = 0;
 	int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2;
 
-	Dialog::drawDialog();
+	Dialog::drawDialog(layerToDraw);
 
 	for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) {
 		g_gui.theme()->drawText(
diff --git a/gui/Tooltip.h b/gui/Tooltip.h
index 6068841..64496ff 100644
--- a/gui/Tooltip.h
+++ b/gui/Tooltip.h
@@ -40,7 +40,7 @@ public:
 
 	void setup(Dialog *parent, Widget *widget, int x, int y);
 
-	void drawDialog();
+	void drawDialog(DrawLayer layerToDraw) override;
 
 	virtual void receivedFocus(int x = -1, int y = -1) {}
 protected:
diff --git a/gui/about.cpp b/gui/about.cpp
index a72a4ed..0d70f3d 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -180,8 +180,8 @@ void AboutDialog::close() {
 	Dialog::close();
 }
 
-void AboutDialog::drawDialog() {
-	Dialog::drawDialog();
+void AboutDialog::drawDialog(DrawLayer layerToDraw) {
+	Dialog::drawDialog(layerToDraw);
 
 	setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h));
 
@@ -268,7 +268,7 @@ void AboutDialog::handleTickle() {
 			_scrollPos = 0;
 			_scrollTime += kScrollStartDelay;
 		}
-		drawDialog();
+		drawDialog(kDrawLayerForeground);
 	}
 }
 
diff --git a/gui/about.h b/gui/about.h
index 9eeb307..b651077 100644
--- a/gui/about.h
+++ b/gui/about.h
@@ -48,7 +48,7 @@ public:
 
 	void open();
 	void close();
-	void drawDialog();
+	void drawDialog(DrawLayer layerToDraw) override;
 	void handleTickle();
 	void handleMouseUp(int x, int y, int button, int clickCount);
 	void handleKeyDown(Common::KeyState state);
diff --git a/gui/console.cpp b/gui/console.cpp
index 942ef61..1c7be32 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -163,18 +163,11 @@ void ConsoleDialog::close() {
 	Dialog::close();
 }
 
-void ConsoleDialog::drawDialog() {
-	g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + _h), ThemeEngine::kDialogBackgroundPlain/*_backgroundType*/);
-	// FIXME: for the old theme the frame around the console vanishes
-	// when any action is processed if we enable this
-	// _drawingHints &= ~THEME_HINT_FIRST_DRAW;
+void ConsoleDialog::drawDialog(DrawLayer layerToDraw) {
+	Dialog::drawDialog(layerToDraw);
 
 	for (int line = 0; line < _linesPerPage; line++)
 		drawLine(line, false);
-
-	// Draw the scrollbar
-	_scrollBar->markAsDirty();
-	_scrollBar->draw();
 }
 
 void ConsoleDialog::drawLine(int line, bool restoreBg) {
@@ -188,7 +181,6 @@ void ConsoleDialog::drawLine(int line, bool restoreBg) {
 	if (restoreBg) {
 		Common::Rect r(_x, y - 2, _x + _pageWidth * kConsoleCharWidth, y+kConsoleLineHeight);
 		g_gui.theme()->restoreBackground(r);
-		g_gui.theme()->addDirtyRect(r);
 	}
 
 	for (int column = 0; column < limit; column++) {
@@ -201,8 +193,6 @@ void ConsoleDialog::drawLine(int line, bool restoreBg) {
 		g_gui.theme()->drawChar(Common::Rect(x, y, x+kConsoleCharWidth, y+kConsoleLineHeight), c, _font);
 		x += kConsoleCharWidth;
 	}
-
-	g_gui.theme()->updateScreen();
 }
 
 void ConsoleDialog::reflowLayout() {
diff --git a/gui/console.h b/gui/console.h
index 430d5b9..04ad552 100644
--- a/gui/console.h
+++ b/gui/console.h
@@ -132,7 +132,7 @@ public:
 
 	void open();
 	void close();
-	void drawDialog();
+	void drawDialog(DrawLayer layerToDraw) override;
 
 	void handleTickle();
 	void reflowLayout();
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 408387b..6f4e8e6 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -161,11 +161,12 @@ void Dialog::markWidgetsAsDirty() {
 	}
 }
 
-void Dialog::drawDialog() {
+void Dialog::drawDialog(DrawLayer layerToDraw) {
 
 	if (!isVisible())
 		return;
 
+	g_gui.theme()->_layerToDraw = layerToDraw;
 	g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _backgroundType);
 
 	markWidgetsAsDirty();
diff --git a/gui/dialog.h b/gui/dialog.h
index 8f3b234..efa6f76 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -92,7 +92,7 @@ protected:
 	void markWidgetsAsDirty();
 
 	/** Draw the dialog in its entirety (background and widgets) */
-	virtual void drawDialog();
+	virtual void drawDialog(DrawLayer layerToDraw);
 
 	/** Draw only the dialog's widgets */
 	void drawWidgets();
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 7c00c68..9515d1b 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -224,20 +224,33 @@ void GuiManager::redraw() {
 		case kRedrawFull:
 		case kRedrawTopDialog:
 			_theme->clearAll();
-			_theme->openDialog(true, ThemeEngine::kShadingNone);
+			_theme->drawToBackbuffer();
 
-			for (DialogStack::size_type i = 0; i < _dialogStack.size() - 1; i++)
-				_dialogStack[i]->drawDialog();
-
-			_theme->finishBuffering();
+			for (DialogStack::size_type i = 0; i < _dialogStack.size() - 1; i++) {
+				_dialogStack[i]->drawDialog(kDrawLayerBackground);
+				_dialogStack[i]->drawDialog(kDrawLayerForeground);
+			}
 
 			// fall through
 
 		case kRedrawOpenDialog:
-			_theme->updateScreen(false);
-			_theme->openDialog(true, shading);
-			_dialogStack.top()->drawDialog();
-			_theme->finishBuffering();
+			// This case is an optimization to avoid redrawing the whole dialog
+			// stack when opening a new dialog.
+
+			_theme->drawToBackbuffer();
+
+			if (_redrawStatus == kRedrawOpenDialog && _dialogStack.size() > 1) {
+				Dialog *previousDialog = _dialogStack[_dialogStack.size() - 2];
+				previousDialog->drawDialog(kDrawLayerForeground);
+			}
+
+			_theme->applyScreenShading(shading);
+			_dialogStack.top()->drawDialog(kDrawLayerBackground);
+
+			_theme->drawToScreen();
+			_theme->copyBackBufferToScreen();
+
+			_dialogStack.top()->drawDialog(kDrawLayerForeground);
 			break;
 
 		default:
@@ -245,6 +258,7 @@ void GuiManager::redraw() {
 	}
 
 	// Redraw the widgets that are marked as dirty
+	_theme->drawToScreen();
 	_dialogStack.top()->drawWidgets();
 
 	_theme->updateScreen();
diff --git a/gui/massadd.cpp b/gui/massadd.cpp
index 34e1ab4..db569fa 100644
--- a/gui/massadd.cpp
+++ b/gui/massadd.cpp
@@ -274,7 +274,7 @@ void MassAddDialog::handleTickle() {
 		_list->scrollToEnd();
 	}
 
-	drawDialog();
+	drawDialog(kDrawLayerForeground);
 }
 
 
diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp
index f59a89e..40af769 100644
--- a/gui/widgets/popup.cpp
+++ b/gui/widgets/popup.cpp
@@ -37,7 +37,6 @@ class PopUpDialog : public Dialog {
 protected:
 	PopUpWidget	*_popUpBoss;
 	int			_clickX, _clickY;
-	byte		*_buffer;
 	int			_selection;
 	uint32		_openTime;
 	bool		_twoColumns;
@@ -49,7 +48,7 @@ protected:
 public:
 	PopUpDialog(PopUpWidget *boss, int clickX, int clickY);
 
-	void drawDialog();
+	void drawDialog(DrawLayer layerToDraw) override;
 
 	void handleMouseUp(int x, int y, int button, int clickCount);
 	void handleMouseWheel(int x, int y, int direction);	// Scroll through entries with scroll wheel
@@ -70,9 +69,9 @@ protected:
 PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY)
 	: Dialog(0, 0, 16, 16),
 	_popUpBoss(boss) {
+	_backgroundType = ThemeEngine::kDialogBackgroundNone;
 
 	_openTime = 0;
-	_buffer = nullptr;
 	_entriesPerColumn = 1;
 
 	// Copy the selection index
@@ -148,7 +147,9 @@ PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY)
 	_clickY = clickY - _y;
 }
 
-void PopUpDialog::drawDialog() {
+void PopUpDialog::drawDialog(DrawLayer layerToDraw) {
+	Dialog::drawDialog(layerToDraw);
+
 	// Draw the menu border
 	g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), 0);
 





More information about the Scummvm-git-logs mailing list