Remove legacy callDrawGlFunction2 from HWUI

Bug: 151439970
Test: CtsUiRenderingTestCases passes

Change-Id: I1c29df17bb6e8b078467edf73cb3547db6948cdd
This commit is contained in:
John Reck
2020-06-25 17:14:13 -07:00
parent cf9d4f5451
commit aa4c982294
24 changed files with 70 additions and 356 deletions

View File

@@ -1227,28 +1227,19 @@ public final class ViewRootImpl implements ViewParent,
}
}
@UnsupportedAppUsage
public void detachFunctor(long functor) {
if (mAttachInfo.mThreadedRenderer != null) {
// Fence so that any pending invokeFunctor() messages will be processed
// before we return from detachFunctor.
mAttachInfo.mThreadedRenderer.stopDrawing();
}
}
/**
* Does nothing; Here only because of @UnsupportedAppUsage
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
publicAlternatives = "Use {@link android.webkit.WebView} instead")
public void detachFunctor(long functor) { }
/**
* Schedules the functor for execution in either kModeProcess or
* kModeProcessNoContext, depending on whether or not there is an EGLContext.
*
* @param functor The native functor to invoke
* @param waitForCompletion If true, this will not return until the functor
* has invoked. If false, the functor may be invoked
* asynchronously.
* Does nothing; Here only because of @UnsupportedAppUsage
*/
@UnsupportedAppUsage
public static void invokeFunctor(long functor, boolean waitForCompletion) {
ThreadedRenderer.invokeFunctor(functor, waitForCompletion);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
publicAlternatives = "Use {@link android.webkit.WebView} instead")
public static void invokeFunctor(long functor, boolean waitForCompletion) { }
/**
* @param animator animator to register with the hardware renderer

View File

@@ -77,73 +77,41 @@ public final class WebViewDelegate {
}
/**
* Returns {@code true} if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor})
* and {@code false} otherwise.
*
* Throws {@link UnsupportedOperationException}
* @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
@Deprecated
public boolean canInvokeDrawGlFunctor(View containerView) {
return true;
throw new UnsupportedOperationException();
}
/**
* Invokes the draw GL functor. If waitForCompletion is {@code false} the functor
* may be invoked asynchronously.
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
* Throws {@link UnsupportedOperationException}
* @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
@Deprecated
public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor,
boolean waitForCompletion) {
ViewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion);
throw new UnsupportedOperationException();
}
/**
* Calls the function specified with the nativeDrawGLFunctor functor pointer. This
* functionality is used by the WebView for calling into their renderer from the
* framework display lists.
*
* @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()})
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
* @throws IllegalArgumentException if the canvas is not hardware accelerated
* Throws {@link UnsupportedOperationException}
* @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
@Deprecated
public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
throw new IllegalArgumentException(canvas.getClass().getName()
+ " is not a DisplayList canvas");
}
((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
throw new UnsupportedOperationException();
}
/**
* Calls the function specified with the nativeDrawGLFunctor functor pointer. This
* functionality is used by the WebView for calling into their renderer from the
* framework display lists.
*
* @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()})
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
* @param releasedRunnable Called when this nativeDrawGLFunctor is no longer referenced by this
* canvas, so is safe to be destroyed.
* @throws IllegalArgumentException if the canvas is not hardware accelerated
* Throws {@link UnsupportedOperationException}
* @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
@Deprecated
public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
@Nullable Runnable releasedRunnable) {
if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
throw new IllegalArgumentException(canvas.getClass().getName()
+ " is not a DisplayList canvas");
}
((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
throw new UnsupportedOperationException();
}
/**

View File

@@ -872,11 +872,6 @@ public class HardwareRenderer {
}
}
/** @hide */
public static void invokeFunctor(long functor, boolean waitForCompletion) {
nInvokeFunctor(functor, waitForCompletion);
}
/**
* b/68769804: For low FPS experiments.
*
@@ -1246,8 +1241,6 @@ public class HardwareRenderer {
private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
private static native long nCreateTextureLayer(long nativeProxy);
private static native void nBuildLayer(long nativeProxy, long node);

View File

@@ -17,11 +17,9 @@
package android.graphics;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Pools.SynchronizedPool;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
/**
* A Canvas implementation that records view system drawing operations for deferred rendering.
@@ -146,43 +144,9 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
}
///////////////////////////////////////////////////////////////////////////
// Functor
// WebView
///////////////////////////////////////////////////////////////////////////
/**
* Records the functor specified with the drawGLFunction function pointer. This is
* functionality used by webview for calling into their renderer from our display lists.
*
* @param drawGLFunction A native function pointer
*
* @hide
* @deprecated Use {@link #drawWebViewFunctor(int)}
*/
@Deprecated
public void callDrawGLFunction2(long drawGLFunction) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
}
/**
* Records the functor specified with the drawGLFunction function pointer. This is
* functionality used by webview for calling into their renderer from our display lists.
*
* @param drawGLFunctor A native function pointer
* @param releasedCallback Called when the display list is destroyed, and thus
* the functor is no longer referenced by this canvas's display list.
*
* NOTE: The callback does *not* necessarily mean that there are no longer
* any references to the functor, just that the reference from this specific
* canvas's display list has been released.
*
* @hide
* @deprecated Use {@link #drawWebViewFunctor(int)}
*/
@Deprecated
public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
}
/**
* Calls the provided functor that was created via WebViewFunctor_create()
* @hide
@@ -273,13 +237,6 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
}
// ------------------ Fast JNI ------------------------
@FastNative
private static native void nCallDrawGLFunction(long renderer,
long drawGLFunction, Runnable releasedCallback);
// ------------------ Critical JNI ------------------------
@CriticalNative

View File

@@ -1,32 +0,0 @@
/*
* 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.
*/
#pragma once
#include <utils/Functor.h>
#include <utils/RefBase.h>
namespace android {
namespace uirenderer {
class GlFunctorLifecycleListener : public VirtualLightRefBase {
public:
virtual ~GlFunctorLifecycleListener() {}
virtual void onGlFunctorReleased(Functor* functor) = 0;
};
} // namespace uirenderer
} // namespace android

View File

@@ -843,9 +843,4 @@ void SkiaCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
LOG_ALWAYS_FATAL("SkiaCanvas can't directly draw RenderNodes");
}
void SkiaCanvas::callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) {
LOG_ALWAYS_FATAL("SkiaCanvas can't directly draw GL Content");
}
} // namespace android

View File

@@ -152,8 +152,6 @@ public:
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
virtual void callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) override;
virtual void drawPicture(const SkPicture& picture) override;
protected:

View File

@@ -20,7 +20,6 @@
#include <utils/Functor.h>
#include <androidfw/ResourceTypes.h>
#include "GlFunctorLifecycleListener.h"
#include "Properties.h"
#include "utils/Macros.h"
@@ -162,8 +161,7 @@ public:
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
virtual void callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) = 0;
virtual void drawWebViewFunctor(int /*functor*/) {
LOG_ALWAYS_FATAL("Not supported");
}

View File

@@ -67,40 +67,8 @@ private:
JavaVM* mVm;
jobject mRunnable;
};
class GlFunctorReleasedCallbackBridge : public GlFunctorLifecycleListener {
public:
GlFunctorReleasedCallbackBridge(JNIEnv* env, jobject javaCallback) {
mLooper = Looper::getForThread();
mMessage = new InvokeRunnableMessage(env, javaCallback);
}
virtual void onGlFunctorReleased(Functor* functor) override {
mLooper->sendMessage(mMessage, 0);
}
private:
sp<Looper> mLooper;
sp<InvokeRunnableMessage> mMessage;
};
#endif
// ---------------- @FastNative -----------------------------
static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
#ifdef __ANDROID__ // Layoutlib does not support GL
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
sp<GlFunctorReleasedCallbackBridge> bridge;
if (releasedCallback) {
bridge = new GlFunctorReleasedCallbackBridge(env, releasedCallback);
}
canvas->callDrawGLFunction(functor, bridge.get());
#endif
}
// ---------------- @CriticalNative -------------------------
static jlong android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
@@ -183,12 +151,6 @@ static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAM
const char* const kClassPathName = "android/graphics/RecordingCanvas";
static JNINativeMethod gMethods[] = {
// ------------ @FastNative ------------------
{ "nCallDrawGLFunction", "(JJLjava/lang/Runnable;)V",
(void*) android_view_DisplayListCanvas_callDrawGLFunction },
// ------------ @CriticalNative --------------
{ "nCreateDisplayListCanvas", "(JII)J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
{ "nResetDisplayListCanvas", "(JJII)V", (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },

View File

@@ -256,12 +256,6 @@ static void android_view_ThreadedRenderer_registerVectorDrawableAnimator(JNIEnv*
rootRenderNode->addVectorDrawableAnimator(animator);
}
static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
jlong functorPtr, jboolean waitForCompletion) {
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
RenderProxy::invokeFunctor(functor, waitForCompletion);
}
static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -684,7 +678,6 @@ static const JNINativeMethod gMethods[] = {
(void*)android_view_ThreadedRenderer_registerAnimatingRenderNode},
{"nRegisterVectorDrawableAnimator", "(JJ)V",
(void*)android_view_ThreadedRenderer_registerVectorDrawableAnimator},
{"nInvokeFunctor", "(JZ)V", (void*)android_view_ThreadedRenderer_invokeFunctor},
{"nCreateTextureLayer", "(J)J", (void*)android_view_ThreadedRenderer_createTextureLayer},
{"nBuildLayer", "(JJ)V", (void*)android_view_ThreadedRenderer_buildLayer},
{"nCopyLayerInto", "(JJJ)Z", (void*)android_view_ThreadedRenderer_copyLayerInto},

View File

@@ -16,8 +16,6 @@
#pragma once
#include "GlFunctorLifecycleListener.h"
#include <SkCanvas.h>
#include <SkDrawable.h>
@@ -36,44 +34,21 @@ namespace skiapipeline {
*/
class FunctorDrawable : public SkDrawable {
public:
FunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
: mBounds(canvas->getLocalClipBounds())
, mAnyFunctor(std::in_place_type<LegacyFunctor>, functor, listener) {}
FunctorDrawable(int functor, SkCanvas* canvas)
: mBounds(canvas->getLocalClipBounds())
, mAnyFunctor(std::in_place_type<NewFunctor>, functor) {}
, mWebViewHandle(WebViewFunctorManager::instance().handleFor(functor)) {}
virtual ~FunctorDrawable() {}
virtual void syncFunctor(const WebViewSyncData& data) const {
if (mAnyFunctor.index() == 0) {
std::get<0>(mAnyFunctor).handle->sync(data);
} else {
(*(std::get<1>(mAnyFunctor).functor))(DrawGlInfo::kModeSync, nullptr);
}
mWebViewHandle->sync(data);
}
protected:
virtual SkRect onGetBounds() override { return mBounds; }
const SkRect mBounds;
struct LegacyFunctor {
explicit LegacyFunctor(Functor* functor, GlFunctorLifecycleListener* listener)
: functor(functor), listener(listener) {}
Functor* functor;
sp<GlFunctorLifecycleListener> listener;
};
struct NewFunctor {
explicit NewFunctor(int functor) {
handle = WebViewFunctorManager::instance().handleFor(functor);
}
sp<WebViewFunctor::Handle> handle;
};
std::variant<NewFunctor, LegacyFunctor> mAnyFunctor;
sp<WebViewFunctor::Handle> mWebViewHandle;
};
} // namespace skiapipeline

View File

@@ -18,7 +18,6 @@
#include <GrContext.h>
#include <private/hwui/DrawGlInfo.h>
#include "FunctorDrawable.h"
#include "GlFunctorLifecycleListener.h"
#include "GrBackendSurface.h"
#include "GrRenderTarget.h"
#include "GrRenderTargetContext.h"
@@ -32,14 +31,6 @@ namespace android {
namespace uirenderer {
namespace skiapipeline {
GLFunctorDrawable::~GLFunctorDrawable() {
if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
if (lp->listener) {
lp->listener->onGlFunctorReleased(lp->functor);
}
}
}
static void setScissor(int viewportHeight, const SkIRect& clip) {
SkASSERT(!clip.isEmpty());
// transform to Y-flipped GL space, and prevent negatives
@@ -195,11 +186,7 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) {
setScissor(info.height, clipRegion.getBounds());
}
if (mAnyFunctor.index() == 0) {
std::get<0>(mAnyFunctor).handle->drawGl(info);
} else {
(*(std::get<1>(mAnyFunctor).functor))(DrawGlInfo::kModeDraw, &info);
}
mWebViewHandle->drawGl(info);
if (clearStencilAfterFunctor) {
// clear stencil buffer as it may be used by Skia

View File

@@ -33,7 +33,7 @@ class GLFunctorDrawable : public FunctorDrawable {
public:
using FunctorDrawable::FunctorDrawable;
virtual ~GLFunctorDrawable();
virtual ~GLFunctorDrawable() {}
protected:
void onDraw(SkCanvas* canvas) override;

View File

@@ -132,23 +132,6 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
}
}
void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) {
#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(
functor, listener, asSkCanvas());
} else {
functorDrawable =
mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, listener, asSkCanvas());
}
mDisplayList->mChildFunctors.push_back(functorDrawable);
drawDrawable(functorDrawable);
#endif
}
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
FunctorDrawable* functorDrawable;

View File

@@ -72,8 +72,7 @@ public:
virtual void enableZ(bool enableZ) override;
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
virtual void callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) override;
void drawWebViewFunctor(int functor) override;
private:

View File

@@ -121,12 +121,7 @@ std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDra
return nullptr;
}
std::unique_ptr<VkFunctorDrawHandler> draw;
if (mAnyFunctor.index() == 0) {
return std::make_unique<VkFunctorDrawHandler>(std::get<0>(mAnyFunctor).handle, matrix, clip,
image_info);
} else {
LOG_ALWAYS_FATAL("Not implemented");
}
return std::make_unique<VkFunctorDrawHandler>(mWebViewHandle, matrix, clip, image_info);
}
} // namespace skiapipeline

View File

@@ -155,11 +155,7 @@ void VkInteropFunctorDrawable::onDraw(SkCanvas* canvas) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (mAnyFunctor.index() == 0) {
std::get<0>(mAnyFunctor).handle->drawGl(info);
} else {
(*(std::get<1>(mAnyFunctor).functor))(DrawGlInfo::kModeDraw, &info);
}
mWebViewHandle->drawGl(info);
EGLSyncKHR glDrawFinishedFence =
eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_FENCE_KHR, NULL);
@@ -190,15 +186,6 @@ void VkInteropFunctorDrawable::onDraw(SkCanvas* canvas) {
canvas->restore();
}
VkInteropFunctorDrawable::~VkInteropFunctorDrawable() {
if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
if (lp->listener) {
ScopedDrawRequest _drawRequest{};
lp->listener->onGlFunctorReleased(lp->functor);
}
}
}
void VkInteropFunctorDrawable::syncFunctor(const WebViewSyncData& data) const {
ScopedDrawRequest _drawRequest{};
FunctorDrawable::syncFunctor(data);

View File

@@ -35,7 +35,7 @@ class VkInteropFunctorDrawable : public FunctorDrawable {
public:
using FunctorDrawable::FunctorDrawable;
virtual ~VkInteropFunctorDrawable();
virtual ~VkInteropFunctorDrawable() {}
static void vkInvokeFunctor(Functor* functor);

View File

@@ -128,20 +128,6 @@ void RenderProxy::destroy() {
mRenderThread.queue().runSync([=]() { mContext->destroy(); });
}
void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
ATRACE_CALL();
RenderThread& thread = RenderThread::getInstance();
auto invoke = [&thread, functor]() { CanvasContext::invokeFunctor(thread, functor); };
if (waitForCompletion) {
// waitForCompletion = true is expected to be fairly rare and only
// happen in destruction. Thus it should be fine to temporarily
// create a Mutex
thread.queue().runSync(std::move(invoke));
} else {
thread.queue().post(std::move(invoke));
}
}
void RenderProxy::destroyFunctor(int functor) {
ATRACE_CALL();
RenderThread& thread = RenderThread::getInstance();

View File

@@ -82,7 +82,6 @@ public:
int syncAndDrawFrame();
void destroy();
static void invokeFunctor(Functor* functor, bool waitForCompletion);
static void destroyFunctor(int functor);
DeferredLayerUpdater* createTextureLayer();

View File

@@ -287,18 +287,6 @@ public:
static std::unique_ptr<uint16_t[]> asciiToUtf16(const char* str);
class MockFunctor : public Functor {
public:
virtual status_t operator()(int what, void* data) {
mLastMode = what;
return DrawGlInfo::kStatusDone;
}
int getLastMode() const { return mLastMode; }
private:
int mLastMode = -1;
};
static SkColor getColor(const sk_sp<SkSurface>& surface, int x, int y);
static SkRect getClipBounds(const SkCanvas* canvas);
@@ -311,30 +299,32 @@ public:
int glesDraw = 0;
};
static void expectOnRenderThread() { EXPECT_EQ(gettid(), TestUtils::getRenderThreadTid()); }
static void expectOnRenderThread(const std::string_view& function = "unknown") {
EXPECT_EQ(gettid(), TestUtils::getRenderThreadTid()) << "Called on wrong thread: " << function;
}
static WebViewFunctorCallbacks createMockFunctor(RenderMode mode) {
auto callbacks = WebViewFunctorCallbacks{
.onSync =
[](int functor, void* client_data, const WebViewSyncData& data) {
expectOnRenderThread();
expectOnRenderThread("onSync");
sMockFunctorCounts[functor].sync++;
},
.onContextDestroyed =
[](int functor, void* client_data) {
expectOnRenderThread();
expectOnRenderThread("onContextDestroyed");
sMockFunctorCounts[functor].contextDestroyed++;
},
.onDestroyed =
[](int functor, void* client_data) {
expectOnRenderThread();
expectOnRenderThread("onDestroyed");
sMockFunctorCounts[functor].destroyed++;
},
};
switch (mode) {
case RenderMode::OpenGL_ES:
callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) {
expectOnRenderThread();
expectOnRenderThread("draw");
sMockFunctorCounts[functor].glesDraw++;
};
break;

View File

@@ -42,14 +42,3 @@ RENDERTHREAD_TEST(CanvasContext, create) {
canvasContext->destroy();
}
RENDERTHREAD_TEST(CanvasContext, invokeFunctor) {
TestUtils::MockFunctor functor;
CanvasContext::invokeFunctor(renderThread, &functor);
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
// we currently don't support OpenGL WebViews on the Vulkan backend
ASSERT_EQ(functor.getLastMode(), DrawGlInfo::kModeProcessNoContext);
} else {
ASSERT_EQ(functor.getLastMode(), DrawGlInfo::kModeProcess);
}
}

View File

@@ -231,39 +231,41 @@ TEST(RenderNode, multiTreeValidity) {
}
TEST(RenderNode, releasedCallback) {
class DecRefOnReleased : public GlFunctorLifecycleListener {
public:
explicit DecRefOnReleased(int* refcnt) : mRefCnt(refcnt) {}
void onGlFunctorReleased(Functor* functor) override { *mRefCnt -= 1; }
private:
int* mRefCnt;
};
int refcnt = 0;
sp<DecRefOnReleased> listener(new DecRefOnReleased(&refcnt));
Functor noopFunctor;
int functor = WebViewFunctor_create(
nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
auto node = TestUtils::createNode(0, 0, 200, 400, [&](RenderProperties& props, Canvas& canvas) {
refcnt++;
canvas.callDrawGLFunction(&noopFunctor, listener.get());
canvas.drawWebViewFunctor(functor);
});
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
EXPECT_EQ(1, refcnt);
TestUtils::runOnRenderThreadUnmanaged([&] (RenderThread&) {
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
});
auto& counts = TestUtils::countsForFunctor(functor);
EXPECT_EQ(1, counts.sync);
EXPECT_EQ(0, counts.destroyed);
TestUtils::recordNode(*node, [&](Canvas& canvas) {
refcnt++;
canvas.callDrawGLFunction(&noopFunctor, listener.get());
canvas.drawWebViewFunctor(functor);
});
EXPECT_EQ(2, refcnt);
EXPECT_EQ(1, counts.sync);
EXPECT_EQ(0, counts.destroyed);
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
EXPECT_EQ(1, refcnt);
TestUtils::runOnRenderThreadUnmanaged([&] (RenderThread&) {
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
});
EXPECT_EQ(2, counts.sync);
EXPECT_EQ(0, counts.destroyed);
WebViewFunctor_release(functor);
EXPECT_EQ(2, counts.sync);
EXPECT_EQ(0, counts.destroyed);
TestUtils::recordNode(*node, [](Canvas& canvas) {});
EXPECT_EQ(1, refcnt);
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
EXPECT_EQ(0, refcnt);
TestUtils::runOnRenderThreadUnmanaged([&] (RenderThread&) {
TestUtils::syncHierarchyPropertiesAndDisplayList(node);
});
EXPECT_EQ(2, counts.sync);
EXPECT_EQ(1, counts.destroyed);
}
RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {

View File

@@ -48,7 +48,10 @@ TEST(SkiaDisplayList, reset) {
SkCanvas dummyCanvas;
RenderNodeDrawable drawable(nullptr, &dummyCanvas);
skiaDL->mChildNodes.emplace_back(nullptr, &dummyCanvas);
GLFunctorDrawable functorDrawable(nullptr, nullptr, &dummyCanvas);
int functor1 = WebViewFunctor_create(
nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
GLFunctorDrawable functorDrawable{functor1, &dummyCanvas};
WebViewFunctor_release(functor1);
skiaDL->mChildFunctors.push_back(&functorDrawable);
skiaDL->mMutableImages.push_back(nullptr);
skiaDL->appendVD(nullptr);
@@ -97,16 +100,13 @@ TEST(SkiaDisplayList, syncContexts) {
SkiaDisplayList skiaDL;
SkCanvas dummyCanvas;
TestUtils::MockFunctor functor;
GLFunctorDrawable functorDrawable(&functor, nullptr, &dummyCanvas);
skiaDL.mChildFunctors.push_back(&functorDrawable);
int functor2 = WebViewFunctor_create(
int functor1 = WebViewFunctor_create(
nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
auto& counts = TestUtils::countsForFunctor(functor2);
auto& counts = TestUtils::countsForFunctor(functor1);
skiaDL.mChildFunctors.push_back(
skiaDL.allocateDrawable<GLFunctorDrawable>(functor2, &dummyCanvas));
WebViewFunctor_release(functor2);
skiaDL.allocateDrawable<GLFunctorDrawable>(functor1, &dummyCanvas));
WebViewFunctor_release(functor1);
SkRect bounds = SkRect::MakeWH(200, 200);
VectorDrawableRoot vectorDrawable(new VectorDrawable::Group());
@@ -120,7 +120,6 @@ TEST(SkiaDisplayList, syncContexts) {
});
});
EXPECT_EQ(functor.getLastMode(), DrawGlInfo::kModeSync);
EXPECT_EQ(counts.sync, 1);
EXPECT_EQ(counts.destroyed, 0);
EXPECT_EQ(vectorDrawable.mutateProperties()->getBounds(), bounds);