Index: wp-includes/class-wp-theme.php
===================================================================
--- wp-includes/class-wp-theme.php	(revision 20148)
+++ wp-includes/class-wp-theme.php	(working copy)
@@ -113,6 +113,14 @@
 	private $parent;
 
 	/**
+	 * URL to the theme root, usually an absolute URL to wp-content/themes
+	 *
+	 * @access private
+	 * var string
+	 */
+	private $theme_root_uri;
+
+	/**
 	 * Flag for whether the theme's textdomain is loaded.
 	 *
 	 * @access private
@@ -789,18 +797,21 @@
 	/**
 	 * Returns the URL to the directory of the theme root.
 	 *
-	 * This is typically the absolute path to wp-content/themes.
+	 * This is typically the absolute URL to wp-content/themes. This forms the basis
+	 * for all other URLs returned by WP_Theme, so we pass it to the public function
+	 * get_theme_root_uri() and allow it to run the theme_root_uri filter.
 	 *
+	 * @uses get_theme_root_uri()
+	 *
 	 * @since 3.4.0
 	 * @access public
 	 *
 	 * @return string Theme root URI.
 	 */
 	public function get_theme_root_uri() {
-		if ( 0 === strpos( WP_CONTENT_DIR, $this->theme_root ) )
-			return str_replace( WP_CONTENT_DIR, content_url(), $this->theme_root );
-		// Give up, send it off to the filter.
-		return get_theme_root_uri( $this->stylesheet );
+		if ( ! isset( $this->theme_root_uri ) )
+			$this->theme_root_uri = get_theme_root_uri( $this->stylesheet, $this->theme_root );
+		return $this->theme_root_uri;
 	}
 
 	/**
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 20161)
+++ wp-includes/theme.php	(working copy)
@@ -525,13 +525,22 @@
  *
  * @since 1.5.0
  *
- * @param string $stylesheet_or_template The stylesheet or template name of the theme
+ * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme.
+ * 	Default is to leverage the main theme root.
+ * @param string $theme_root Optional. The theme root for which calculations can be based, preventing
+ * 	the need for a get_raw_theme_root() call.
  * @return string Themes URI.
  */
-function get_theme_root_uri( $stylesheet_or_template = false ) {
+function get_theme_root_uri( $stylesheet_or_template = false, $theme_root = false ) {
 	global $wp_theme_directories;
 
-	if ( $stylesheet_or_template && $theme_root = get_raw_theme_root( $stylesheet_or_template ) ) {
+	if ( count( $wp_theme_directories ) <= 1 )
+		return apply_filters( 'theme_root_uri', content_url( 'themes' ), get_option('siteurl'), $stylesheet_or_template );
+
+	if ( $stylesheet_or_template && ! $theme_root )
+		$theme_root = get_raw_theme_root( $stylesheet_or_template );
+
+	if ( $stylesheet_or_template && $theme_root ) {
 		if ( in_array( $theme_root, (array) $wp_theme_directories ) ) {
 			// Absolute path. Make an educated guess. YMMV -- but note the filter below.
 			if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) )
