Move OpenGL specific details behind renderPipeline interface.
Test: new and existing unit tests still pass. Change-Id: I6164f30f45ebe450788ed8d949eca5af9a44e585
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
61
libs/hwui/tests/unit/CanvasContextTests.cpp
Normal file
61
libs/hwui/tests/unit/CanvasContextTests.cpp
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user