Move OpenGL specific details behind renderPipeline interface.

Test: new and existing unit tests still pass.
Change-Id: I6164f30f45ebe450788ed8d949eca5af9a44e585
This commit is contained in:
Derek Sollenberger
2016-10-25 12:09:18 -04:00
parent be9a73063c
commit daf7229047
8 changed files with 120 additions and 24 deletions

View File

@@ -266,6 +266,7 @@ LOCAL_SRC_FILES += \
tests/unit/BakedOpDispatcherTests.cpp \
tests/unit/BakedOpRendererTests.cpp \
tests/unit/BakedOpStateTests.cpp \
tests/unit/CanvasContextTests.cpp \
tests/unit/CanvasStateTests.cpp \
tests/unit/ClipAreaTests.cpp \
tests/unit/DamageAccumulatorTests.cpp \

View File

@@ -97,6 +97,31 @@ void CanvasContext::destroyLayer(RenderNode* node) {
}
}
void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
ATRACE_CALL();
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
OpenGLPipeline::invokeFunctor(thread, functor);
break;
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
break;
}
}
void CanvasContext::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
OpenGLPipeline::prepareToDraw(thread, bitmap);
break;
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
break;
}
}
CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory,
std::unique_ptr<IRenderPipeline> renderPipeline)
@@ -425,8 +450,11 @@ void CanvasContext::draw() {
GpuMemoryTracker::onFrameCompleted();
#ifdef BUGREPORT_FONT_CACHE_USAGE
Caches& caches = Caches::getInstance();
caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
auto renderType = Properties::getRenderPipelineType();
if (RenderPipelineType::OpenGL == renderType) {
Caches& caches = Caches::getInstance();
caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
}
#endif
}
@@ -456,16 +484,6 @@ void CanvasContext::prepareAndDraw(RenderNode* node) {
}
}
void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
ATRACE_CALL();
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
if (thread.eglManager().hasEglContext()) {
mode = DrawGlInfo::kModeProcess;
}
thread.renderState().invokeFunctor(functor, mode, nullptr);
}
void CanvasContext::markLayerInUse(RenderNode* node) {
if (mPrefetchedLayers.erase(node)) {
node->decStrong(nullptr);
@@ -520,10 +538,6 @@ void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
for (const sp<RenderNode>& node : mRenderNodes) {
node->destroyHardwareResources(observer);
}
Caches& caches = Caches::getInstance();
// Make sure to release all the textures we were owning as there won't
// be another draw
caches.textureCache.resetMarkInUse(this);
mRenderPipeline->onDestroyHardwareResources();
}
}

View File

@@ -85,6 +85,10 @@ public:
*/
static void destroyLayer(RenderNode* node);
static void invokeFunctor(const RenderThread& thread, Functor* functor);
static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
/*
* If Properties::isSkiaEnabled() is true then this will return the Skia
* grContext associated with the current RenderPipeline.
@@ -121,8 +125,6 @@ public:
void destroyHardwareResources(TreeObserver* observer);
static void trimMemory(RenderThread& thread, int level);
static void invokeFunctor(RenderThread& thread, Functor* functor);
DeferredLayerUpdater* createTextureLayer();
void stopDrawing();

View File

@@ -165,6 +165,10 @@ bool OpenGLPipeline::isContextReady() {
}
void OpenGLPipeline::onDestroyHardwareResources() {
Caches& caches = Caches::getInstance();
// Make sure to release all the textures we were owning as there won't
// be another draw
caches.textureCache.resetMarkInUse(this);
mRenderThread.renderState().flush(Caches::FlushMode::Layers);
}
@@ -225,6 +229,21 @@ void OpenGLPipeline::destroyLayer(RenderNode* node) {
}
}
void OpenGLPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
if (Caches::hasInstance() && thread.eglManager().hasEglContext()) {
ATRACE_NAME("Bitmap#prepareToDraw task");
Caches::getInstance().textureCache.prefetch(bitmap);
}
}
void OpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
if (thread.eglManager().hasEglContext()) {
mode = DrawGlInfo::kModeProcess;
}
thread.renderState().invokeFunctor(functor, mode, nullptr);
}
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */

View File

@@ -56,6 +56,8 @@ public:
bool createOrUpdateLayer(RenderNode* node,
const DamageAccumulator& damageAccumulator) override;
static void destroyLayer(RenderNode* node);
static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
static void invokeFunctor(const RenderThread& thread, Functor* functor);
private:
EglManager& mEglManager;

View File

@@ -618,10 +618,7 @@ int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top,
}
CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, Bitmap* bitmap) {
if (Caches::hasInstance() && args->thread->eglManager().hasEglContext()) {
ATRACE_NAME("Bitmap#prepareToDraw task");
Caches::getInstance().textureCache.prefetch(args->bitmap);
}
CanvasContext::prepareToDraw(*args->thread, args->bitmap);
args->bitmap->unref();
args->bitmap = nullptr;
return nullptr;

View File

@@ -89,8 +89,8 @@ public:
void pushBackFrameCallback(IFrameCallback* callback);
TimeLord& timeLord() { return mTimeLord; }
RenderState& renderState() { return *mRenderState; }
EglManager& eglManager() { return *mEglManager; }
RenderState& renderState() const { return *mRenderState; }
EglManager& eglManager() const { return *mEglManager; }
JankTracker& jankTracker() { return *mJankTracker; }
const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "AnimationContext.h"
#include "IContextFactory.h"
#include "renderthread/CanvasContext.h"
#include "tests/common/TestUtils.h"
using namespace android;
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
class ContextFactory : public IContextFactory {
public:
virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
return new AnimationContext(clock);
}
};
RENDERTHREAD_TEST(CanvasContext, create) {
auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
ContextFactory contextFactory;
std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
renderThread, false, rootNode.get(), &contextFactory));
ASSERT_FALSE(canvasContext->hasSurface());
canvasContext->destroy(nullptr);
}
class TestFunctor : public Functor {
public:
bool didProcess = false;
virtual status_t operator ()(int what, void* data) {
if (what == DrawGlInfo::kModeProcess) { didProcess = true; }
return DrawGlInfo::kStatusDone;
}
};
RENDERTHREAD_TEST(CanvasContext, invokeFunctor) {
TestFunctor functor;
ASSERT_FALSE(functor.didProcess);
CanvasContext::invokeFunctor(renderThread, &functor);
ASSERT_TRUE(functor.didProcess);
}