diff --git a/android/app/build.gradle b/android/app/build.gradle
index 815a15e752..0d07848820 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -23,12 +23,7 @@ android {
                     '-DBUILD_BRANCH=' + BUILD_BRANCH
             }
         }
-        compileOptions {
-            sourceCompatibility JavaVersion.VERSION_1_8
-            targetCompatibility JavaVersion.VERSION_1_8
-        }
     }
-
     buildTypes {
         applicationVariants.all { variant ->
             variant.outputs.all {
@@ -43,17 +38,23 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
-
     externalNativeBuild {
         cmake {
             path '../../CMakeLists.txt'
         }
     }
+    buildToolsVersion '27.0.3'
+    dexOptions {
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
 }
 
 dependencies {
     implementation 'com.google.vr:sdk-audio:1.80.0'
     implementation 'com.google.vr:sdk-base:1.80.0'
-    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
 }
 
diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp
new file mode 100644
index 0000000000..6725256feb
--- /dev/null
+++ b/android/app/src/main/cpp/native.cpp
@@ -0,0 +1,28 @@
+
+#include <QtCore/QDebug>
+#include <QtCore/QThread>
+#include <QtAndroidExtras/QAndroidJniObject>
+
+#include <android/log.h>
+#include <android/asset_manager.h>
+#include <android/asset_manager_jni.h>
+
+extern "C" {
+
+JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) {
+    qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
+}
+
+JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
+    qDebug() << "nativeOnPause";
+}
+
+JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnResume(JNIEnv* env, jobject obj) {
+    qDebug() << "nativeOnResume";
+}
+
+JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnExitVr(JNIEnv* env, jobject obj) {
+    qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
+}
+
+}
diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml
index 896b3cf10e..8c732aac40 100644
--- a/interface/resources/qml/hifi/Desktop.qml
+++ b/interface/resources/qml/hifi/Desktop.qml
@@ -22,10 +22,6 @@ OriginalDesktop.Desktop {
         acceptedButtons: Qt.NoButton
     }
 
-    // The tool window, one instance
-    property alias toolWindow: toolWindow
-    ToolWindow { id: toolWindow }
-
     Action {
         text: "Open Browser"
         shortcut: "Ctrl+B"
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index a0163a0b53..2d8a63c24d 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -210,14 +210,7 @@
 #include "commerce/QmlCommerce.h"
 
 #include "webbrowser/WebBrowserSuggestionsEngine.h"
-#if defined(Q_OS_ANDROID)
-#include <QtAndroidExtras/QAndroidJniObject>
-#include <android/log.h>
-#include <android/asset_manager.h>
-#include <android/asset_manager_jni.h>
-#endif
-// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
-// FIXME seems to be broken.
+
 #if defined(Q_OS_WIN)
 #include <VersionHelpers.h>
 
@@ -232,35 +225,17 @@
 #undef QT_BOOTSTRAPPED
 #endif
 
+// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
+// FIXME seems to be broken.
 extern "C" {
  _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 }
 #endif
 
 #if defined(Q_OS_ANDROID)
-extern "C" {
- 
-JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) {
-    qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
-}
-
-JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
-    qDebug() << "nativeOnPause";
-}
-
-JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnResume(JNIEnv* env, jobject obj) {
-    qDebug() << "nativeOnResume";
-}
-
-
-
-JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnExitVr(JNIEnv* env, jobject obj) {
-    qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
-}
-
-
-}
+#include <android/log.h>
 #endif
+
 enum ApplicationEvent {
     // Execute a lambda function
     Lambda = QEvent::User + 1,
@@ -270,7 +245,6 @@ enum ApplicationEvent {
     Idle,
 };
 
-
 class RenderEventHandler : public QObject {
     using Parent = QObject;
     Q_OBJECT
@@ -2232,7 +2206,9 @@ void Application::initializeGL() {
     _chromiumShareContext->setObjectName("ChromiumShareContext");
     _chromiumShareContext->create(_glWidget->qglContext());
     _chromiumShareContext->makeCurrent();
-    qt_gl_set_global_share_context(_chromiumShareContext->getContext());
+    if (nsightActive()) {
+        qt_gl_set_global_share_context(_chromiumShareContext->getContext());
+    }
 
     _glWidget->makeCurrent();
     gpu::Context::init<gpu::gl::GLBackend>();
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
index 0facf5f2d0..567a7e355c 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
@@ -884,6 +884,7 @@ void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
 }
 
 void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) {
+#if !defined(Q_OS_ANDROID)
     auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
     withMainThreadContext([&] {
         GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture());
@@ -891,14 +892,10 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
         GLuint fbo[2] {0, 0};
 
         // need mipmaps for blitting texture
-#if !defined(Q_OS_ANDROID)
-		glGenerateTextureMipmap(sourceTexture);
-#endif
+        glGenerateTextureMipmap(sourceTexture);
 
         // create 2 fbos (one for initial texture, second for scaled one)
-#if !defined(Q_OS_ANDROID)
-	glCreateFramebuffers(2, fbo);
-#endif
+        glCreateFramebuffers(2, fbo);
 
         // setup source fbo
         glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
@@ -928,13 +925,13 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
         } else {
             newY = (target->height() - newHeight) / 2;
         }
-#if !defined(Q_OS_ANDROID)
+
         glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, GL_NEAREST);
-#endif
 
         // don't delete the textures!
         glDeleteFramebuffers(2, fbo);
         *fenceSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
     });
+#endif
 }
 
diff --git a/libraries/render-utils/src/RenderCommonTask.cpp b/libraries/render-utils/src/RenderCommonTask.cpp
new file mode 100644
index 0000000000..3c45e1dcf5
--- /dev/null
+++ b/libraries/render-utils/src/RenderCommonTask.cpp
@@ -0,0 +1,238 @@
+//
+//  Created by Bradley Austin Davis on 2018/01/09
+//  Copyright 2013-2018 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "RenderCommonTask.h"
+
+#include <PerfStat.h>
+#include <PathUtils.h>
+#include <ViewFrustum.h>
+#include <gpu/Context.h>
+
+#include <render/CullTask.h>
+#include <render/FilterTask.h>
+#include <render/SortTask.h>
+#include <render/DrawTask.h>
+#include <render/DrawStatus.h>
+#include <render/DrawSceneOctree.h>
+#include <render/BlurTask.h>
+
+#include "LightingModel.h"
+#include "StencilMaskPass.h"
+#include "DebugDeferredBuffer.h"
+#include "DeferredFramebuffer.h"
+#include "DeferredLightingEffect.h"
+#include "SurfaceGeometryPass.h"
+#include "FramebufferCache.h"
+#include "TextureCache.h"
+#include "ZoneRenderer.h"
+#include "FadeEffect.h"
+#include "RenderUtilsLogging.h"
+
+#include "AmbientOcclusionEffect.h"
+#include "AntialiasingEffect.h"
+#include "ToneMappingEffect.h"
+#include "SubsurfaceScattering.h"
+#include "DrawHaze.h"
+#include "BloomEffect.h"
+#include "HighlightEffect.h"
+
+#include <sstream>
+
+using namespace render;
+extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false);
+
+void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) {
+    timer = _gpuTimer;
+    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
+        _gpuTimer->begin(batch);
+    });
+}
+
+void EndGPURangeTimer::run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer) {
+    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
+        timer->end(batch);
+    });
+    
+    auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
+    config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage());
+}
+
+DrawOverlay3D::DrawOverlay3D(bool opaque) :
+    _shapePlumber(std::make_shared<ShapePlumber>()),
+    _opaquePass(opaque) {
+    initOverlay3DPipelines(*_shapePlumber);
+}
+
+void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
+    assert(renderContext->args);
+    assert(renderContext->args->hasViewFrustum());
+
+    auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
+
+    const auto& inItems = inputs.get0();
+    const auto& lightingModel = inputs.get1();
+    
+    config->setNumDrawn((int)inItems.size());
+    emit config->numDrawnChanged();
+
+    if (!inItems.empty()) {
+        RenderArgs* args = renderContext->args;
+
+        // Clear the framebuffer without stereo
+        // Needs to be distinct from the other batch because using the clear call 
+        // while stereo is enabled triggers a warning
+        if (_opaquePass) {
+            gpu::doInBatch(args->_context, [&](gpu::Batch& batch){
+                batch.enableStereo(false);
+                batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false);
+            });
+        }
+
+        // Render the items
+        gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
+            args->_batch = &batch;
+            batch.setViewportTransform(args->_viewport);
+            batch.setStateScissorRect(args->_viewport);
+
+            glm::mat4 projMat;
+            Transform viewMat;
+            args->getViewFrustum().evalProjectionMatrix(projMat);
+            args->getViewFrustum().evalViewTransform(viewMat);
+
+            batch.setProjectionTransform(projMat);
+            batch.setViewTransform(viewMat);
+
+            // Setup lighting model for all items;
+            batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
+
+            renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn);
+            args->_batch = nullptr;
+        });
+    }
+}
+
+void CompositeHUD::run(const RenderContextPointer& renderContext) {
+    assert(renderContext->args);
+    assert(renderContext->args->_context);
+
+    // We do not want to render HUD elements in secondary camera
+    if (renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
+        return;
+    }
+
+    // Grab the HUD texture
+    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
+        if (renderContext->args->_hudOperator) {
+            renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
+        }
+    });
+}
+
+void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
+    assert(renderContext->args);
+    assert(renderContext->args->_context);
+
+    RenderArgs* renderArgs = renderContext->args;
+    auto blitFbo = renderArgs->_blitFramebuffer;
+
+    if (!blitFbo) {
+        qCWarning(renderutils) << "Blit::run - no blit frame buffer.";
+        return;
+    }
+
+    // Determine size from viewport
+    int width = renderArgs->_viewport.z;
+    int height = renderArgs->_viewport.w;
+
+    // Blit primary to blit FBO
+    auto primaryFbo = srcFramebuffer;
+
+    gpu::doInBatch(renderArgs->_context, [&](gpu::Batch& batch) {
+        batch.setFramebuffer(blitFbo);
+
+        if (renderArgs->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
+            if (renderArgs->isStereo()) {
+                gpu::Vec4i srcRectLeft;
+                srcRectLeft.z = width / 2;
+                srcRectLeft.w = height;
+
+                gpu::Vec4i srcRectRight;
+                srcRectRight.x = width / 2;
+                srcRectRight.z = width;
+                srcRectRight.w = height;
+
+                gpu::Vec4i destRectLeft;
+                destRectLeft.x = srcRectLeft.z;
+                destRectLeft.z = srcRectLeft.x;
+                destRectLeft.y = srcRectLeft.y;
+                destRectLeft.w = srcRectLeft.w;
+
+                gpu::Vec4i destRectRight;
+                destRectRight.x = srcRectRight.z;
+                destRectRight.z = srcRectRight.x;
+                destRectRight.y = srcRectRight.y;
+                destRectRight.w = srcRectRight.w;
+
+                // Blit left to right and right to left in stereo
+                batch.blit(primaryFbo, srcRectRight, blitFbo, destRectLeft);
+                batch.blit(primaryFbo, srcRectLeft, blitFbo, destRectRight);
+            } else {
+                gpu::Vec4i srcRect;
+                srcRect.z = width;
+                srcRect.w = height;
+
+                gpu::Vec4i destRect;
+                destRect.x = width;
+                destRect.y = 0;
+                destRect.z = 0;
+                destRect.w = height;
+
+                batch.blit(primaryFbo, srcRect, blitFbo, destRect);
+            }
+        } else {
+            gpu::Vec4i rect;
+            rect.z = width;
+            rect.w = height;
+
+            batch.blit(primaryFbo, rect, blitFbo, rect);
+        }
+    });
+}
+
+void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) {
+    assert(renderContext->args);
+    assert(renderContext->args->_context);
+
+    RenderArgs* args = renderContext->args;
+
+    // Return view frustum
+    auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
+    if (!viewFrustum) {
+        viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum());
+    } else {
+        *viewFrustum = args->getViewFrustum();
+    }
+
+    // Return shadow frustum
+    auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName());
+    for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
+        auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>();
+        if (lightStage) {
+            auto globalShadow = lightStage->getCurrentKeyShadow();
+
+            if (globalShadow && i<(int)globalShadow->getCascadeCount()) {
+                auto& cascade = globalShadow->getCascade(i);
+                shadowFrustum = cascade.getFrustum();
+            } else {
+                shadowFrustum.reset();
+            }
+        } else {
+            shadowFrustum.reset();
+        }
+    }
+}
diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h
new file mode 100644
index 0000000000..767b6893cd
--- /dev/null
+++ b/libraries/render-utils/src/RenderCommonTask.h
@@ -0,0 +1,116 @@
+//
+//  Created by Bradley Austin Davis on 2018/01/09
+//  Copyright 2013-2018 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi_RenderCommonTask_h
+#define hifi_RenderCommonTask_h
+
+#include <gpu/Pipeline.h>
+#include <render/RenderFetchCullSortTask.h>
+#include "LightingModel.h"
+
+class BeginGPURangeTimer {
+public:
+    using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
+
+    BeginGPURangeTimer(const std::string& name) : _gpuTimer(std::make_shared<gpu::RangeTimer>(name)) {}
+
+    void run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer);
+
+protected:
+    gpu::RangeTimerPointer _gpuTimer;
+};
+
+using GPURangeTimerConfig = render::GPUJobConfig;
+
+class EndGPURangeTimer {
+public:
+    using Config = GPURangeTimerConfig;
+    using JobModel = render::Job::ModelI<EndGPURangeTimer, gpu::RangeTimerPointer, Config>;
+
+    EndGPURangeTimer() {}
+
+    void configure(const Config& config) {}
+    void run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer);
+
+protected:
+};
+
+class DrawOverlay3DConfig : public render::Job::Config {
+    Q_OBJECT
+        Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
+        Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
+public:
+    int getNumDrawn() { return numDrawn; }
+    void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
+
+    int maxDrawn{ -1 };
+
+signals:
+    void numDrawnChanged();
+    void dirty();
+
+protected:
+    int numDrawn{ 0 };
+};
+
+class DrawOverlay3D {
+public:
+    using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
+
+    using Config = DrawOverlay3DConfig;
+    using JobModel = render::Job::ModelI<DrawOverlay3D, Inputs, Config>;
+
+    DrawOverlay3D(bool opaque);
+
+    void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
+    void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
+
+protected:
+    render::ShapePlumberPointer _shapePlumber;
+    int _maxDrawn; // initialized by Config
+    bool _opaquePass{ true };
+};
+
+class CompositeHUD {
+public:
+    using JobModel = render::Job::Model<CompositeHUD>;
+
+    CompositeHUD() {}
+    void run(const render::RenderContextPointer& renderContext);
+};
+
+class Blit {
+public:
+    using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
+
+    void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
+};
+
+class ExtractFrustums {
+public:
+
+    enum Frustum {
+        SHADOW_CASCADE0_FRUSTUM = 0,
+        SHADOW_CASCADE1_FRUSTUM,
+        SHADOW_CASCADE2_FRUSTUM,
+        SHADOW_CASCADE3_FRUSTUM,
+
+        SHADOW_CASCADE_FRUSTUM_COUNT,
+
+        VIEW_FRUSTUM = SHADOW_CASCADE_FRUSTUM_COUNT,
+
+        FRUSTUM_COUNT
+    };
+
+    using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
+    using JobModel = render::Job::ModelO<ExtractFrustums, Output>;
+
+    void run(const render::RenderContextPointer& renderContext, Output& output);
+};
+
+#endif // hifi_RenderDeferredTask_h
diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp
index f860c0494e..30c8c7d604 100644
--- a/libraries/render-utils/src/RenderDeferredTask.cpp
+++ b/libraries/render-utils/src/RenderDeferredTask.cpp
@@ -25,6 +25,7 @@
 #include <render/DrawSceneOctree.h>
 #include <render/BlurTask.h>
 
+#include "RenderCommonTask.h"
 #include "LightingModel.h"
 #include "StencilMaskPass.h"
 #include "DebugDeferredBuffer.h"
@@ -289,23 +290,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
     task.addJob<Blit>("Blit", primaryFramebuffer);
 }
 
-void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) {
-    timer = _gpuTimer;
-    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
-        _gpuTimer->begin(batch);
-    });
-}
-
-void EndGPURangeTimer::run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer) {
-    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
-        timer->end(batch);
-    });
-    
-    auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
-    config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage());
-}
-
-
 void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
     assert(renderContext->args);
     assert(renderContext->args->hasViewFrustum());
@@ -410,177 +394,3 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const
     config->setNumDrawn((int)inItems.size());
 }
 
-DrawOverlay3D::DrawOverlay3D(bool opaque) :
-    _shapePlumber(std::make_shared<ShapePlumber>()),
-    _opaquePass(opaque) {
-    initOverlay3DPipelines(*_shapePlumber);
-}
-
-void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
-    assert(renderContext->args);
-    assert(renderContext->args->hasViewFrustum());
-
-    auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
-
-    const auto& inItems = inputs.get0();
-    const auto& lightingModel = inputs.get1();
-    
-    config->setNumDrawn((int)inItems.size());
-    emit config->numDrawnChanged();
-
-    if (!inItems.empty()) {
-        RenderArgs* args = renderContext->args;
-
-        // Clear the framebuffer without stereo
-        // Needs to be distinct from the other batch because using the clear call 
-        // while stereo is enabled triggers a warning
-        if (_opaquePass) {
-            gpu::doInBatch(args->_context, [&](gpu::Batch& batch){
-                batch.enableStereo(false);
-                batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false);
-            });
-        }
-
-        // Render the items
-        gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
-            args->_batch = &batch;
-            batch.setViewportTransform(args->_viewport);
-            batch.setStateScissorRect(args->_viewport);
-
-            glm::mat4 projMat;
-            Transform viewMat;
-            args->getViewFrustum().evalProjectionMatrix(projMat);
-            args->getViewFrustum().evalViewTransform(viewMat);
-
-            batch.setProjectionTransform(projMat);
-            batch.setViewTransform(viewMat);
-
-            // Setup lighting model for all items;
-            batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
-
-            renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn);
-            args->_batch = nullptr;
-        });
-    }
-}
-
-void CompositeHUD::run(const RenderContextPointer& renderContext) {
-    assert(renderContext->args);
-    assert(renderContext->args->_context);
-
-    // We do not want to render HUD elements in secondary camera
-    if (renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
-        return;
-    }
-
-    // Grab the HUD texture
-    gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
-        if (renderContext->args->_hudOperator) {
-            renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
-        }
-    });
-}
-
-void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
-    assert(renderContext->args);
-    assert(renderContext->args->_context);
-
-    RenderArgs* renderArgs = renderContext->args;
-    auto blitFbo = renderArgs->_blitFramebuffer;
-
-    if (!blitFbo) {
-        qCWarning(renderutils) << "Blit::run - no blit frame buffer.";
-        return;
-    }
-
-    // Determine size from viewport
-    int width = renderArgs->_viewport.z;
-    int height = renderArgs->_viewport.w;
-
-    // Blit primary to blit FBO
-    auto primaryFbo = srcFramebuffer;
-
-    gpu::doInBatch(renderArgs->_context, [&](gpu::Batch& batch) {
-        batch.setFramebuffer(blitFbo);
-
-        if (renderArgs->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
-            if (renderArgs->isStereo()) {
-                gpu::Vec4i srcRectLeft;
-                srcRectLeft.z = width / 2;
-                srcRectLeft.w = height;
-
-                gpu::Vec4i srcRectRight;
-                srcRectRight.x = width / 2;
-                srcRectRight.z = width;
-                srcRectRight.w = height;
-
-                gpu::Vec4i destRectLeft;
-                destRectLeft.x = srcRectLeft.z;
-                destRectLeft.z = srcRectLeft.x;
-                destRectLeft.y = srcRectLeft.y;
-                destRectLeft.w = srcRectLeft.w;
-
-                gpu::Vec4i destRectRight;
-                destRectRight.x = srcRectRight.z;
-                destRectRight.z = srcRectRight.x;
-                destRectRight.y = srcRectRight.y;
-                destRectRight.w = srcRectRight.w;
-
-                // Blit left to right and right to left in stereo
-                batch.blit(primaryFbo, srcRectRight, blitFbo, destRectLeft);
-                batch.blit(primaryFbo, srcRectLeft, blitFbo, destRectRight);
-            } else {
-                gpu::Vec4i srcRect;
-                srcRect.z = width;
-                srcRect.w = height;
-
-                gpu::Vec4i destRect;
-                destRect.x = width;
-                destRect.y = 0;
-                destRect.z = 0;
-                destRect.w = height;
-
-                batch.blit(primaryFbo, srcRect, blitFbo, destRect);
-            }
-        } else {
-            gpu::Vec4i rect;
-            rect.z = width;
-            rect.w = height;
-
-            batch.blit(primaryFbo, rect, blitFbo, rect);
-        }
-    });
-}
-
-void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) {
-    assert(renderContext->args);
-    assert(renderContext->args->_context);
-
-    RenderArgs* args = renderContext->args;
-
-    // Return view frustum
-    auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
-    if (!viewFrustum) {
-        viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum());
-    } else {
-        *viewFrustum = args->getViewFrustum();
-    }
-
-    // Return shadow frustum
-    auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName());
-    for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
-        auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>();
-        if (lightStage) {
-            auto globalShadow = lightStage->getCurrentKeyShadow();
-
-            if (globalShadow && i<(int)globalShadow->getCascadeCount()) {
-                auto& cascade = globalShadow->getCascade(i);
-                shadowFrustum = cascade.getFrustum();
-            } else {
-                shadowFrustum.reset();
-            }
-        } else {
-            shadowFrustum.reset();
-        }
-    }
-}
diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h
index e41b7edc77..00804f7e7b 100644
--- a/libraries/render-utils/src/RenderDeferredTask.h
+++ b/libraries/render-utils/src/RenderDeferredTask.h
@@ -16,42 +16,17 @@
 #include <render/RenderFetchCullSortTask.h>
 #include "LightingModel.h"
 
-class BeginGPURangeTimer {
-public:
-    using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
-
-    BeginGPURangeTimer(const std::string& name) : _gpuTimer(std::make_shared<gpu::RangeTimer>(name)) {}
-
-    void run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer);
-
-protected:
-    gpu::RangeTimerPointer _gpuTimer;
-};
-
-using GPURangeTimerConfig = render::GPUJobConfig;
-
-class EndGPURangeTimer {
-public:
-    using Config = GPURangeTimerConfig;
-    using JobModel = render::Job::ModelI<EndGPURangeTimer, gpu::RangeTimerPointer, Config>;
-
-    EndGPURangeTimer() {}
-
-    void configure(const Config& config) {}
-    void run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer);
-
-protected:
-};
-
-class DrawConfig : public render::Job::Config {
+class DrawDeferredConfig : public render::Job::Config {
     Q_OBJECT
     Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY newStats)
     Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
 
 public:
-
     int getNumDrawn() { return _numDrawn; }
-    void setNumDrawn(int numDrawn) { _numDrawn = numDrawn;  emit newStats(); }
+    void setNumDrawn(int numDrawn) {
+        _numDrawn = numDrawn;
+        emit newStats();
+    }
 
     int maxDrawn{ -1 };
 
@@ -65,29 +40,32 @@ protected:
 
 class DrawDeferred {
 public:
-    using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
-    using Config = DrawConfig;
+    using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
+    using Config = DrawDeferredConfig;
     using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>;
 
-    DrawDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
+    DrawDeferred(render::ShapePlumberPointer shapePlumber)
+        : _shapePlumber{ shapePlumber } {}
 
     void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
     void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
 
 protected:
     render::ShapePlumberPointer _shapePlumber;
-    int _maxDrawn; // initialized by Config
+    int _maxDrawn;  // initialized by Config
 };
 
 class DrawStateSortConfig : public render::Job::Config {
     Q_OBJECT
-        Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
-        Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
-        Q_PROPERTY(bool stateSort MEMBER stateSort NOTIFY dirty)
+    Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
+    Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
+    Q_PROPERTY(bool stateSort MEMBER stateSort NOTIFY dirty)
 public:
-
     int getNumDrawn() { return numDrawn; }
-    void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
+    void setNumDrawn(int num) {
+        numDrawn = num;
+        emit numDrawnChanged();
+    }
 
     int maxDrawn{ -1 };
     bool stateSort{ true };
@@ -102,101 +80,32 @@ protected:
 
 class DrawStateSortDeferred {
 public:
-    using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
+    using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
 
     using Config = DrawStateSortConfig;
     using JobModel = render::Job::ModelI<DrawStateSortDeferred, Inputs, Config>;
 
-    DrawStateSortDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
+    DrawStateSortDeferred(render::ShapePlumberPointer shapePlumber)
+        : _shapePlumber{ shapePlumber } {}
 
-    void configure(const Config& config) { _maxDrawn = config.maxDrawn; _stateSort = config.stateSort; }
+    void configure(const Config& config) {
+        _maxDrawn = config.maxDrawn;
+        _stateSort = config.stateSort;
+    }
     void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
 
 protected:
     render::ShapePlumberPointer _shapePlumber;
-    int _maxDrawn; // initialized by Config
+    int _maxDrawn;  // initialized by Config
     bool _stateSort;
 };
 
-class DrawOverlay3DConfig : public render::Job::Config {
-    Q_OBJECT
-    Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
-    Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
-public:
-    int getNumDrawn() { return numDrawn; }
-    void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
-
-    int maxDrawn{ -1 };
-
-signals:
-    void numDrawnChanged();
-    void dirty();
-
-protected:
-    int numDrawn{ 0 };
-};
-
-class DrawOverlay3D {
-public:
-    using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
-
-    using Config = DrawOverlay3DConfig;
-    using JobModel = render::Job::ModelI<DrawOverlay3D, Inputs, Config>;
-
-    DrawOverlay3D(bool opaque);
-
-    void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
-    void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
-
-protected:
-    render::ShapePlumberPointer _shapePlumber;
-    int _maxDrawn; // initialized by Config
-    bool _opaquePass { true };
-};
-
-class CompositeHUD {
-public:
-    using JobModel = render::Job::Model<CompositeHUD>;
-
-    CompositeHUD() {}
-    void run(const render::RenderContextPointer& renderContext);
-};
-
-class Blit {
-public:
-    using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
-
-    void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
-};
-
-class ExtractFrustums {
-public:
-
-    enum Frustum {
-        SHADOW_CASCADE0_FRUSTUM = 0,
-        SHADOW_CASCADE1_FRUSTUM,
-        SHADOW_CASCADE2_FRUSTUM,
-        SHADOW_CASCADE3_FRUSTUM,
-
-        SHADOW_CASCADE_FRUSTUM_COUNT,
-
-        VIEW_FRUSTUM = SHADOW_CASCADE_FRUSTUM_COUNT,
-
-        FRUSTUM_COUNT
-    };
-
-    using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
-    using JobModel = render::Job::ModelO<ExtractFrustums, Output>;
-
-    void run(const render::RenderContextPointer& renderContext, Output& output);
-};
-
 class RenderDeferredTaskConfig : public render::Task::Config {
     Q_OBJECT
-        Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
-        Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
-        Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
-        Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
+    Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
+    Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
+    Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
+    Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
 public:
     float fadeScale{ 0.5f };
     float fadeDuration{ 3.0f };
@@ -205,7 +114,6 @@ public:
 
 signals:
     void dirty();
-
 };
 
 class RenderDeferredTask {
@@ -220,9 +128,11 @@ public:
     void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
 
 private:
-
-    static const render::Varying addSelectItemJobs(JobModel& task, const char* selectionName, 
-                                                   const render::Varying& metas, const render::Varying& opaques, const render::Varying& transparents);
+    static const render::Varying addSelectItemJobs(JobModel& task,
+                                                   const char* selectionName,
+                                                   const render::Varying& metas,
+                                                   const render::Varying& opaques,
+                                                   const render::Varying& transparents);
 };
 
-#endif // hifi_RenderDeferredTask_h
+#endif  // hifi_RenderDeferredTask_h
diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp
index a0efc694cd..3567588797 100755
--- a/libraries/render-utils/src/RenderForwardTask.cpp
+++ b/libraries/render-utils/src/RenderForwardTask.cpp
@@ -11,26 +11,28 @@
 //
 
 #include "RenderForwardTask.h"
-#include "RenderDeferredTask.h"
 
 #include <PerfStat.h>
 #include <PathUtils.h>
 #include <ViewFrustum.h>
 #include <gpu/Context.h>
+#include <gpu/Texture.h>
+#include <gpu/StandardShaderLib.h>
+
 #include "StencilMaskPass.h"
 #include "ZoneRenderer.h"
 #include "FadeEffect.h"
 #include "BackgroundStage.h"
-
 #include "FramebufferCache.h"
 #include "TextureCache.h"
-#include <gpu/Texture.h>
-#include <gpu/StandardShaderLib.h>
+#include "RenderCommonTask.h"
 
 #include "nop_frag.h"
 
 using namespace render;
-extern void initForwardPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
+extern void initForwardPipelines(ShapePlumber& plumber,
+                                 const render::ShapePipeline::BatchSetter& batchSetter,
+                                 const render::ShapePipeline::ItemSetter& itemSetter);
 
 void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
     auto items = input.get<Input>();
@@ -43,12 +45,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
     // Extract opaques / transparents / lights / metas / overlays / background
     const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
     const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
-//    const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
+    //    const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
     const auto& metas = items.get0()[RenderFetchCullSortTask::META];
-//    const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
-//    const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
+    //    const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
+    //    const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
     //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
-//    const auto& spatialSelection = items[1];
+    //    const auto& spatialSelection = items[1];
+
+    fadeEffect->build(task, opaques);
 
     const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer");
 
@@ -60,11 +64,11 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
     // Filter zones from the general metas bucket
     const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas);
 
-//    task.addJob<DrawBackground>("DrawBackground", background);
+    //    task.addJob<DrawBackground>("DrawBackground", background);
     // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
     task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel);
 
-    { // Debug the bounds of the rendered items, still look at the zbuffer
+    {  // Debug the bounds of the rendered items, still look at the zbuffer
 
         task.addJob<DrawBounds>("DrawMetaBounds", metas);
         task.addJob<DrawBounds>("DrawBounds", opaques);
@@ -74,13 +78,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
 
     task.addJob<Draw>("DrawTransparents", transparents, shapePlumber);
 
+    // Composite the HUD and HUD overlays
+    task.addJob<CompositeHUD>("HUD");
 
     // Blit!
     task.addJob<Blit>("Blit", framebuffer);
 }
 
-void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
-        gpu::FramebufferPointer& framebuffer) {
+void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) {
     auto framebufferCache = DependencyManager::get<FramebufferCache>();
     auto framebufferSize = framebufferCache->getFrameBufferSize();
     glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
@@ -95,11 +100,13 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
 
         auto colorFormat = gpu::Element::COLOR_SRGBA_32;
         auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
-        auto colorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
+        auto colorTexture =
+            gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
         _framebuffer->setRenderBuffer(0, colorTexture);
 
-        auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
-        auto depthTexture = gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
+        auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL);  // Depth24_Stencil8 texel format
+        auto depthTexture =
+            gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
         _framebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
     }
 
@@ -110,18 +117,15 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
         batch.setStateScissorRect(args->_viewport);
 
         batch.setFramebuffer(_framebuffer);
-        batch.clearFramebuffer(
-            gpu::Framebuffer::BUFFER_COLOR0 |
-            gpu::Framebuffer::BUFFER_DEPTH |
-            gpu::Framebuffer::BUFFER_STENCIL,
-            vec4(vec3(0), 1), 1.0, 0, true);
+        batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH |
+                                   gpu::Framebuffer::BUFFER_STENCIL,
+                               vec4(vec3(0), 1), 1.0, 0, true);
     });
 
     framebuffer = _framebuffer;
 }
 
-void Draw::run(const RenderContextPointer& renderContext,
-        const Inputs& items) {
+void Draw::run(const RenderContextPointer& renderContext, const Inputs& items) {
     RenderArgs* args = renderContext->args;
 
     gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
@@ -174,8 +178,7 @@ void Stencil::run(const RenderContextPointer& renderContext) {
     args->_batch = nullptr;
 }
 
-void DrawBackground::run(const RenderContextPointer& renderContext,
-        const Inputs& background) {
+void DrawBackground::run(const RenderContextPointer& renderContext, const Inputs& background) {
     RenderArgs* args = renderContext->args;
 
     gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
@@ -197,5 +200,3 @@ void DrawBackground::run(const RenderContextPointer& renderContext,
     });
     args->_batch = nullptr;
 }
-
-
diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp
index 19ffe96148..97cc3426f2 100644
--- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp
+++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp
@@ -548,15 +548,12 @@ void OffscreenQmlSurface::render() {
 
     PROFILE_RANGE(render_qml_gl, __FUNCTION__)
     _canvas->makeCurrent();
-
     _renderControl->sync();
     _quickWindow->setRenderTarget(_fbo, QSize(_size.x, _size.y));
 
     GLuint texture = offscreenTextures.getNextTexture(_size);
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
-#if !defined(Q_OS_ANDROID)
-	glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
-#endif
+    glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     _renderControl->render();
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@@ -843,7 +840,7 @@ QQmlContext* OffscreenQmlSurface::contextForUrl(const QUrl& qmlSource, QQuickIte
 
     QQmlContext* targetContext = parent ? QQmlEngine::contextForObject(parent) : _qmlContext;
     if (!targetContext) {
-    	targetContext = _qmlContext;
+        targetContext = _qmlContext;
     }
     if (_rootItem && forceNewContext) {
         targetContext = new QQmlContext(targetContext);