New WebViewFunctor API
Should function alongside existing functor API.
Bug: 120997728
Test: hwuiunit passes
Change-Id: I8f6143d0be1111431b55016f34de319f6b8c8910
diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h
index af3a056..cf2f93b 100644
--- a/libs/hwui/pipeline/skia/FunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/FunctorDrawable.h
@@ -21,7 +21,9 @@
#include <SkCanvas.h>
#include <SkDrawable.h>
+#include <WebViewFunctorManager.h>
#include <utils/Functor.h>
+#include <variant>
namespace android {
namespace uirenderer {
@@ -35,17 +37,43 @@
class FunctorDrawable : public SkDrawable {
public:
FunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
- : mFunctor(functor), mListener(listener), mBounds(canvas->getLocalClipBounds()) {}
+ : 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) {}
+
virtual ~FunctorDrawable() {}
- virtual void syncFunctor() const = 0;
+ 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);
+ }
+ }
protected:
virtual SkRect onGetBounds() override { return mBounds; }
- Functor* mFunctor;
- sp<GlFunctorLifecycleListener> mListener;
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;
};
} // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index 4a87e75..240efb4 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -17,29 +17,28 @@
#include "GLFunctorDrawable.h"
#include <GrContext.h>
#include <private/hwui/DrawGlInfo.h>
+#include "FunctorDrawable.h"
#include "GlFunctorLifecycleListener.h"
+#include "GrBackendSurface.h"
+#include "GrRenderTarget.h"
+#include "GrRenderTargetContext.h"
#include "RenderNode.h"
#include "SkAndroidFrameworkUtils.h"
#include "SkClipStack.h"
#include "SkRect.h"
-#include "GrBackendSurface.h"
-#include "GrRenderTarget.h"
-#include "GrRenderTargetContext.h"
namespace android {
namespace uirenderer {
namespace skiapipeline {
GLFunctorDrawable::~GLFunctorDrawable() {
- if (mListener.get() != nullptr) {
- mListener->onGlFunctorReleased(mFunctor);
+ if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
+ if (lp->listener) {
+ lp->listener->onGlFunctorReleased(lp->functor);
+ }
}
}
-void GLFunctorDrawable::syncFunctor() const {
- (*mFunctor)(DrawGlInfo::kModeSync, nullptr);
-}
-
static void setScissor(int viewportHeight, const SkIRect& clip) {
SkASSERT(!clip.isEmpty());
// transform to Y-flipped GL space, and prevent negatives
@@ -49,14 +48,14 @@
}
static bool GetFboDetails(SkCanvas* canvas, GLuint* outFboID, SkISize* outFboSize) {
- GrRenderTargetContext *renderTargetContext =
+ GrRenderTargetContext* renderTargetContext =
canvas->internal_private_accessTopLayerRenderTargetContext();
if (!renderTargetContext) {
ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw");
return false;
}
- GrRenderTarget *renderTarget = renderTargetContext->accessRenderTarget();
+ GrRenderTarget* renderTarget = renderTargetContext->accessRenderTarget();
if (!renderTarget) {
ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw");
return false;
@@ -94,16 +93,16 @@
sk_sp<SkSurface> tmpSurface;
// we are in a state where there is an unclipped saveLayer
if (fboID != 0 && !surfaceBounds.contains(clipBounds)) {
-
// create an offscreen layer and clear it
- SkImageInfo surfaceInfo = canvas->imageInfo().makeWH(clipBounds.width(), clipBounds.height());
- tmpSurface = SkSurface::MakeRenderTarget(canvas->getGrContext(), SkBudgeted::kYes,
- surfaceInfo);
+ SkImageInfo surfaceInfo =
+ canvas->imageInfo().makeWH(clipBounds.width(), clipBounds.height());
+ tmpSurface =
+ SkSurface::MakeRenderTarget(canvas->getGrContext(), SkBudgeted::kYes, surfaceInfo);
tmpSurface->getCanvas()->clear(SK_ColorTRANSPARENT);
GrGLFramebufferInfo fboInfo;
if (!tmpSurface->getBackendRenderTarget(SkSurface::kFlushWrite_BackendHandleAccess)
- .getGLFramebufferInfo(&fboInfo)) {
+ .getGLFramebufferInfo(&fboInfo)) {
ALOGW("Unable to extract renderTarget info from offscreen canvas; aborting GLFunctor");
return;
}
@@ -144,7 +143,7 @@
bool clearStencilAfterFunctor = false;
if (CC_UNLIKELY(clipRegion.isComplex())) {
// clear the stencil
- //TODO: move stencil clear and canvas flush to SkAndroidFrameworkUtils::clipWithStencil
+ // TODO: move stencil clear and canvas flush to SkAndroidFrameworkUtils::clipWithStencil
glDisable(GL_SCISSOR_TEST);
glStencilMask(0x1);
glClearStencil(0);
@@ -163,7 +162,7 @@
// GL ops get inserted here if previous flush is missing, which could dirty the stencil
bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(tmpCanvas);
- tmpCanvas->flush(); //need this flush for the single op that draws into the stencil
+ tmpCanvas->flush(); // need this flush for the single op that draws into the stencil
// ensure that the framebuffer that the webview will render into is bound before after we
// draw into the stencil
@@ -188,7 +187,11 @@
setScissor(info.height, clipRegion.getBounds());
}
- (*mFunctor)(DrawGlInfo::kModeDraw, &info);
+ if (mAnyFunctor.index() == 0) {
+ std::get<0>(mAnyFunctor).handle->drawGl(info);
+ } else {
+ (*(std::get<1>(mAnyFunctor).functor))(DrawGlInfo::kModeDraw, &info);
+ }
if (clearStencilAfterFunctor) {
// clear stencil buffer as it may be used by Skia
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
index 215979c..2ea4f67 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -31,11 +31,9 @@
*/
class GLFunctorDrawable : public FunctorDrawable {
public:
- GLFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
- : FunctorDrawable(functor, listener, canvas) {}
- virtual ~GLFunctorDrawable();
+ using FunctorDrawable::FunctorDrawable;
- void syncFunctor() const override;
+ virtual ~GLFunctorDrawable();
protected:
void onDraw(SkCanvas* canvas) override;
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index f08ac17..eed1942 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <utils/MathUtils.h>
#include "LayerDrawable.h"
+#include <utils/MathUtils.h>
#include "GrBackendSurface.h"
#include "SkColorFilter.h"
@@ -44,10 +44,9 @@
if (!matrix.isScaleTranslate()) return true;
// We only care about meaningful scale here
- bool noScale = MathUtils::isOne(matrix.getScaleX())
- && MathUtils::isOne(matrix.getScaleY());
- bool pixelAligned = SkScalarIsInt(matrix.getTranslateX())
- && SkScalarIsInt(matrix.getTranslateY());
+ bool noScale = MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY());
+ bool pixelAligned =
+ SkScalarIsInt(matrix.getTranslateX()) && SkScalarIsInt(matrix.getTranslateY());
return !(noScale && pixelAligned);
}
@@ -120,11 +119,12 @@
// Integer translation is defined as when src rect and dst rect align fractionally.
// Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works
// only for SrcOver blending and without color filter (readback uses Src blending).
- bool isIntegerTranslate = isBasicallyTranslate(totalMatrix)
- && SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX])
- == SkScalarFraction(skiaSrcRect.fLeft)
- && SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY])
- == SkScalarFraction(skiaSrcRect.fTop);
+ bool isIntegerTranslate =
+ isBasicallyTranslate(totalMatrix) &&
+ SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX]) ==
+ SkScalarFraction(skiaSrcRect.fLeft) &&
+ SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY]) ==
+ SkScalarFraction(skiaSrcRect.fTop);
if (layer->getForceFilter() || !isIntegerTranslate) {
paint.setFilterQuality(kLow_SkFilterQuality);
}
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 95dc6d0..7cd515a 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -32,8 +32,8 @@
public:
explicit LayerDrawable(DeferredLayerUpdater* layerUpdater) : mLayerUpdater(layerUpdater) {}
- static bool DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer,
- const SkRect* srcRect, const SkRect* dstRect, bool useLayerTransform);
+ static bool DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer, const SkRect* srcRect,
+ const SkRect* dstRect, bool useLayerTransform);
protected:
virtual SkRect onGetBounds() override {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 4494cb0..df1537e 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -127,6 +127,7 @@
mNode.markDrawEnd(mCanvas);
}
}
+
private:
SkCanvas& mCanvas;
RenderNode& mNode;
@@ -140,7 +141,7 @@
// ensures that we paint the layer even if it is not currently visible in the
// event that the properties change and it becomes visible.
if ((mProjectedDisplayList == nullptr && !renderNode->isRenderable()) ||
- (renderNode->nothingToDraw() && mComposeLayer)) {
+ (renderNode->nothingToDraw() && mComposeLayer)) {
return;
}
@@ -234,8 +235,8 @@
// we need to restrict the portion of the surface drawn to the size of the renderNode.
SkASSERT(renderNode->getLayerSurface()->width() >= bounds.width());
SkASSERT(renderNode->getLayerSurface()->height() >= bounds.height());
- canvas->drawImageRect(renderNode->getLayerSurface()->makeImageSnapshot().get(),
- bounds, bounds, &paint);
+ canvas->drawImageRect(renderNode->getLayerSurface()->makeImageSnapshot().get(), bounds,
+ bounds, &paint);
if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) {
renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index 073b481..562a3b2 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -15,11 +15,11 @@
*/
#include "ShaderCache.h"
-#include <algorithm>
#include <log/log.h>
-#include <thread>
-#include <array>
#include <openssl/sha.h>
+#include <algorithm>
+#include <array>
+#include <thread>
#include "FileBlobCache.h"
#include "Properties.h"
#include "utils/TraceUtils.h"
@@ -44,8 +44,7 @@
}
bool ShaderCache::validateCache(const void* identity, ssize_t size) {
- if (nullptr == identity && size == 0)
- return true;
+ if (nullptr == identity && size == 0) return true;
if (nullptr == identity || size < 0) {
if (CC_UNLIKELY(Properties::debugLevel & kDebugCaches)) {
@@ -66,8 +65,7 @@
auto key = sIDKey;
auto loaded = mBlobCache->get(&key, sizeof(key), hash.data(), hash.size());
- if (loaded && std::equal(hash.begin(), hash.end(), mIDHash.begin()))
- return true;
+ if (loaded && std::equal(hash.begin(), hash.end(), mIDHash.begin())) return true;
if (CC_UNLIKELY(Properties::debugLevel & kDebugCaches)) {
ALOGW("ShaderCache::validateCache cache validation fails");
@@ -119,7 +117,7 @@
int maxTries = 3;
while (valueSize > mObservedBlobValueSize && maxTries > 0) {
mObservedBlobValueSize = std::min(valueSize, maxValueSize);
- void *newValueBuffer = realloc(valueBuffer, mObservedBlobValueSize);
+ void* newValueBuffer = realloc(valueBuffer, mObservedBlobValueSize);
if (!newValueBuffer) {
free(valueBuffer);
return nullptr;
@@ -133,7 +131,7 @@
return nullptr;
}
if (valueSize > mObservedBlobValueSize) {
- ALOGE("ShaderCache::load value size is too big %d", (int) valueSize);
+ ALOGE("ShaderCache::load value size is too big %d", (int)valueSize);
free(valueBuffer);
return nullptr;
}
diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h
index 82804cf..d41aadb 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.h
+++ b/libs/hwui/pipeline/skia/ShaderCache.h
@@ -16,12 +16,12 @@
#pragma once
+#include <GrContextOptions.h>
#include <cutils/compiler.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
-#include <GrContextOptions.h>
namespace android {
@@ -52,7 +52,7 @@
* the initialized state the load and store methods will return without
* performing any cache operations.
*/
- virtual void initShaderDiskCache(const void *identity, ssize_t size);
+ virtual void initShaderDiskCache(const void* identity, ssize_t size);
virtual void initShaderDiskCache() { initShaderDiskCache(nullptr, 0); }
@@ -153,7 +153,7 @@
/**
* "mObservedBlobValueSize" is the maximum value size observed by the cache reading function.
*/
- size_t mObservedBlobValueSize = 20*1024;
+ size_t mObservedBlobValueSize = 20 * 1024;
/**
* The time in seconds to wait before saving newly inserted cache entries.
@@ -176,7 +176,7 @@
*/
static constexpr uint8_t sIDKey = 0;
- friend class ShaderCacheTestUtils; //used for unit testing
+ friend class ShaderCacheTestUtils; // used for unit testing
};
} /* namespace skiapipeline */
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index ac6f6a3..230065c 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -27,9 +27,9 @@
namespace uirenderer {
namespace skiapipeline {
-void SkiaDisplayList::syncContents() {
+void SkiaDisplayList::syncContents(const WebViewSyncData& data) {
for (auto& functor : mChildFunctors) {
- functor->syncFunctor();
+ functor->syncFunctor(data);
}
for (auto& animatedImage : mAnimatedImages) {
animatedImage->syncProperties();
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index d7879e7..309ec02 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -16,11 +16,11 @@
#pragma once
-#include "hwui/AnimatedImageDrawable.h"
#include "FunctorDrawable.h"
#include "RecordingCanvas.h"
#include "RenderNodeDrawable.h"
#include "TreeInfo.h"
+#include "hwui/AnimatedImageDrawable.h"
#include "utils/LinearAllocator.h"
#include <deque>
@@ -109,7 +109,7 @@
* NOTE: This function can be folded into RenderNode when we no longer need
* to subclass from DisplayList
*/
- void syncContents();
+ void syncContents(const WebViewSyncData& data);
/**
* ONLY to be called by RenderNode::prepareTree in order to prepare this
diff --git a/libs/hwui/pipeline/skia/SkiaMemoryTracer.cpp b/libs/hwui/pipeline/skia/SkiaMemoryTracer.cpp
index ea578cb..e48ecf4 100644
--- a/libs/hwui/pipeline/skia/SkiaMemoryTracer.cpp
+++ b/libs/hwui/pipeline/skia/SkiaMemoryTracer.cpp
@@ -21,16 +21,16 @@
namespace skiapipeline {
SkiaMemoryTracer::SkiaMemoryTracer(std::vector<ResourcePair> resourceMap, bool itemizeType)
- : mResourceMap(resourceMap)
- , mItemizeType(itemizeType)
- , mTotalSize("bytes", 0)
- , mPurgeableSize("bytes", 0) {}
+ : mResourceMap(resourceMap)
+ , mItemizeType(itemizeType)
+ , mTotalSize("bytes", 0)
+ , mPurgeableSize("bytes", 0) {}
SkiaMemoryTracer::SkiaMemoryTracer(const char* categoryKey, bool itemizeType)
- : mCategoryKey(categoryKey)
- , mItemizeType(itemizeType)
- , mTotalSize("bytes", 0)
- , mPurgeableSize("bytes", 0) {}
+ : mCategoryKey(categoryKey)
+ , mItemizeType(itemizeType)
+ , mTotalSize("bytes", 0)
+ , mPurgeableSize("bytes", 0) {}
const char* SkiaMemoryTracer::mapName(const char* resourceName) {
for (auto& resource : mResourceMap) {
@@ -42,7 +42,7 @@
}
void SkiaMemoryTracer::processElement() {
- if(!mCurrentElement.empty()) {
+ if (!mCurrentElement.empty()) {
// Only count elements that contain "size", other values just provide metadata.
auto sizeResult = mCurrentValues.find("size");
if (sizeResult != mCurrentValues.end()) {
@@ -136,8 +136,8 @@
for (const auto& typedValue : namedItem.second) {
TraceValue traceValue = convertUnits(typedValue.second);
const char* entry = (traceValue.count > 1) ? "entries" : "entry";
- log.appendFormat(" %s: %.2f %s (%d %s)\n", typedValue.first,
- traceValue.value, traceValue.units, traceValue.count, entry);
+ log.appendFormat(" %s: %.2f %s (%d %s)\n", typedValue.first, traceValue.value,
+ traceValue.units, traceValue.count, entry);
}
} else {
auto result = namedItem.second.find("size");
diff --git a/libs/hwui/pipeline/skia/SkiaMemoryTracer.h b/libs/hwui/pipeline/skia/SkiaMemoryTracer.h
index abf1f4b..e9a7981 100644
--- a/libs/hwui/pipeline/skia/SkiaMemoryTracer.h
+++ b/libs/hwui/pipeline/skia/SkiaMemoryTracer.h
@@ -50,8 +50,8 @@
}
bool shouldDumpWrappedObjects() const override { return true; }
- void setMemoryBacking(const char*, const char*, const char*) override { }
- void setDiscardableMemoryBacking(const char*, const SkDiscardableMemory&) override { }
+ void setMemoryBacking(const char*, const char*, const char*) override {}
+ void setDiscardableMemoryBacking(const char*, const SkDiscardableMemory&) override {}
private:
struct TraceValue {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 7a255c1..bbc827d 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -183,15 +183,15 @@
} else {
String8 cachesOutput;
mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
- &mRenderThread.renderState());
+ &mRenderThread.renderState());
ALOGE("%s", cachesOutput.string());
if (errorHandler) {
std::ostringstream err;
err << "Unable to create layer for " << node->getName();
const int maxTextureSize = DeviceInfo::get()->maxTextureSize();
err << ", size " << info.width() << "x" << info.height() << " max size "
- << maxTextureSize << " color type " << (int)info.colorType()
- << " has context " << (int)(mRenderThread.getGrContext() != nullptr);
+ << maxTextureSize << " color type " << (int)info.colorType() << " has context "
+ << (int)(mRenderThread.getGrContext() != nullptr);
errorHandler->onError(err.str());
}
}
@@ -300,8 +300,7 @@
mSavePictureProcessor->savePicture(data, mCapturedFile);
} else {
mSavePictureProcessor->savePicture(
- data,
- mCapturedFile + "_" + std::to_string(mCaptureSequence));
+ data, mCapturedFile + "_" + std::to_string(mCaptureSequence));
}
mCaptureSequence--;
}
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 42a411a..c94b24a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -97,8 +97,7 @@
return mLightCenter;
}
- static void updateLighting(const LightGeometry& lightGeometry,
- const LightInfo& lightInfo) {
+ static void updateLighting(const LightGeometry& lightGeometry, const LightInfo& lightInfo) {
mLightRadius = lightGeometry.radius;
mAmbientShadowAlpha = lightInfo.ambientShadowAlpha;
mSpotShadowAlpha = lightInfo.spotShadowAlpha;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index b56c3ef..6eefed9 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -24,8 +24,8 @@
#include "RenderNode.h"
#include "pipeline/skia/AnimatedDrawables.h"
#include "pipeline/skia/GLFunctorDrawable.h"
-#include "pipeline/skia/VkInteropFunctorDrawable.h"
#include "pipeline/skia/VkFunctorDrawable.h"
+#include "pipeline/skia/VkInteropFunctorDrawable.h"
namespace android {
namespace uirenderer {
@@ -95,8 +95,8 @@
drawDrawable(drawable);
}
if (enableReorder) {
- mCurrentBarrier = mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(
- mDisplayList.get());
+ mCurrentBarrier =
+ mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(mDisplayList.get());
drawDrawable(mCurrentBarrier);
}
}
@@ -127,11 +127,25 @@
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
// TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the
// interop is disabled/moved.
- functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor,
- listener, asSkCanvas());
+ functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(
+ functor, listener, asSkCanvas());
} else {
- functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, listener,
- asSkCanvas());
+ functorDrawable =
+ mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, listener, asSkCanvas());
+ }
+ mDisplayList->mChildFunctors.push_back(functorDrawable);
+ drawDrawable(functorDrawable);
+}
+
+void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
+ FunctorDrawable* functorDrawable;
+ if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+ // TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the
+ // interop is disabled.
+ functorDrawable =
+ mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor, asSkCanvas());
+ } else {
+ functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}
mDisplayList->mChildFunctors.push_back(functorDrawable);
drawDrawable(functorDrawable);
@@ -167,7 +181,7 @@
if (colorSpaceFilter) {
if (tmpPaint.getColorFilter()) {
tmpPaint.setColorFilter(SkColorFilter::MakeComposeFilter(
- tmpPaint.refColorFilter(), std::move(colorSpaceFilter)));
+ tmpPaint.refColorFilter(), std::move(colorSpaceFilter)));
} else {
tmpPaint.setColorFilter(std::move(colorSpaceFilter));
}
@@ -248,8 +262,7 @@
filteredPaint.writeable().setFilterQuality(kLow_SkFilterQuality);
}
sk_sp<SkImage> image = bitmap.makeImage();
- mRecorder.drawImageLattice(image, lattice, dst,
- filterPaint(std::move(filteredPaint)),
+ mRecorder.drawImageLattice(image, lattice, dst, filterPaint(std::move(filteredPaint)),
bitmap.palette());
if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
mDisplayList->mMutableImages.push_back(image.get());
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index d6107a9..afeccea 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -74,6 +74,7 @@
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
virtual void callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) override;
+ void drawWebViewFunctor(int functor) override;
private:
RecordingCanvas mRecorder;
diff --git a/libs/hwui/pipeline/skia/SkiaUtils.h b/libs/hwui/pipeline/skia/SkiaUtils.h
index 8344469..fa7f1fe 100644
--- a/libs/hwui/pipeline/skia/SkiaUtils.h
+++ b/libs/hwui/pipeline/skia/SkiaUtils.h
@@ -22,7 +22,7 @@
static inline SkRect SkRectMakeLargest() {
const SkScalar v = SK_ScalarMax;
- return { -v, -v, v, v };
+ return {-v, -v, v, v};
};
} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 437b5dc..b64eb24 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -20,9 +20,9 @@
#include "Readback.h"
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"
+#include "VkInteropFunctorDrawable.h"
#include "renderstate/RenderState.h"
#include "renderthread/Frame.h"
-#include "VkInteropFunctorDrawable.h"
#include <SkSurface.h>
#include <SkTypes.h>
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index 71ad5e1..156f74a 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -17,23 +17,21 @@
#include "VkFunctorDrawable.h"
#include <private/hwui/DrawVkInfo.h>
-#include "thread/ThreadBase.h"
-#include "utils/TimeUtils.h"
#include <GrBackendDrawableInfo.h>
-#include <thread>
+#include <SkImage.h>
#include <utils/Color.h>
#include <utils/Trace.h>
#include <utils/TraceUtils.h>
-#include <SkImage.h>
#include <vk/GrVkTypes.h>
+#include <thread>
+#include "thread/ThreadBase.h"
+#include "utils/TimeUtils.h"
namespace android {
namespace uirenderer {
namespace skiapipeline {
-VkFunctorDrawHandler::VkFunctorDrawHandler(Functor *functor)
- : INHERITED()
- , mFunctor(functor) {}
+VkFunctorDrawHandler::VkFunctorDrawHandler(Functor* functor) : INHERITED(), mFunctor(functor) {}
VkFunctorDrawHandler::~VkFunctorDrawHandler() {
// TODO(cblume) Fill in the DrawVkInfo parameters.
@@ -55,14 +53,12 @@
(*mFunctor)(DrawVkInfo::kModeComposite, &draw_vk_info);
}
-VkFunctorDrawable::VkFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener,
- SkCanvas* canvas)
- : FunctorDrawable(functor, listener, canvas) {}
-
-VkFunctorDrawable::~VkFunctorDrawable() = default;
-
-void VkFunctorDrawable::syncFunctor() const {
- (*mFunctor)(DrawVkInfo::kModeSync, nullptr);
+VkFunctorDrawable::~VkFunctorDrawable() {
+ if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
+ if (lp->listener) {
+ lp->listener->onGlFunctorReleased(lp->functor);
+ }
+ }
}
void VkFunctorDrawable::onDraw(SkCanvas* /*canvas*/) {
@@ -71,12 +67,17 @@
}
std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler(
- GrBackendApi backendApi, const SkMatrix& matrix) {
+ GrBackendApi backendApi, const SkMatrix& matrix) {
if (backendApi != GrBackendApi::kVulkan) {
return nullptr;
}
- std::unique_ptr<VkFunctorDrawHandler> draw(new VkFunctorDrawHandler(mFunctor));
- return std::move(draw);
+ std::unique_ptr<VkFunctorDrawHandler> draw;
+ if (mAnyFunctor.index() == 0) {
+ LOG_ALWAYS_FATAL("Not implemented");
+ return nullptr;
+ } else {
+ return std::make_unique<VkFunctorDrawHandler>(std::get<1>(mAnyFunctor).functor);
+ }
}
} // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.h b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
index 5cd1314..d6fefc1 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
@@ -18,9 +18,9 @@
#include "FunctorDrawable.h"
-#include <utils/RefBase.h>
-#include <ui/GraphicBuffer.h>
#include <SkImageInfo.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/RefBase.h>
namespace android {
namespace uirenderer {
@@ -36,6 +36,7 @@
~VkFunctorDrawHandler() override;
void draw(const GrBackendDrawableInfo& info) override;
+
private:
typedef GpuDrawHandler INHERITED;
@@ -48,17 +49,15 @@
*/
class VkFunctorDrawable : public FunctorDrawable {
public:
- VkFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener,
- SkCanvas* canvas);
- ~VkFunctorDrawable() override;
+ using FunctorDrawable::FunctorDrawable;
- void syncFunctor() const override;
+ ~VkFunctorDrawable() override;
protected:
// SkDrawable functions:
void onDraw(SkCanvas* canvas) override;
- std::unique_ptr<FunctorDrawable::GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi backendApi,
- const SkMatrix& matrix) override;
+ std::unique_ptr<FunctorDrawable::GpuDrawHandler> onSnapGpuDrawHandler(
+ GrBackendApi backendApi, const SkMatrix& matrix) override;
};
} // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
index 8228550..a5faae7 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
@@ -17,13 +17,13 @@
#include "VkInteropFunctorDrawable.h"
#include <private/hwui/DrawGlInfo.h>
-#include "renderthread/EglManager.h"
-#include "thread/ThreadBase.h"
-#include "utils/TimeUtils.h"
-#include <thread>
#include <utils/Color.h>
#include <utils/Trace.h>
#include <utils/TraceUtils.h>
+#include <thread>
+#include "renderthread/EglManager.h"
+#include "thread/ThreadBase.h"
+#include "utils/TimeUtils.h"
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
@@ -44,6 +44,7 @@
class ScopedDrawRequest {
public:
ScopedDrawRequest() { beginDraw(); }
+
private:
void beginDraw() {
std::lock_guard _lock{sLock};
@@ -57,9 +58,7 @@
}
if (!sEglManager.hasEglContext()) {
- sGLDrawThread->queue().runSync([]() {
- sEglManager.initialize();
- });
+ sGLDrawThread->queue().runSync([]() { sEglManager.initialize(); });
}
}
};
@@ -93,14 +92,14 @@
if (!mFrameBuffer.get() || mFBInfo != surfaceInfo) {
// Buffer will be used as an OpenGL ES render target.
mFrameBuffer = new GraphicBuffer(
- //TODO: try to reduce the size of the buffer: possibly by using clip bounds.
- static_cast<uint32_t>(surfaceInfo.width()),
- static_cast<uint32_t>(surfaceInfo.height()),
- ColorTypeToPixelFormat(surfaceInfo.colorType()),
- GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER |
- GraphicBuffer::USAGE_SW_READ_NEVER | GraphicBuffer::USAGE_HW_RENDER,
- std::string("VkInteropFunctorDrawable::onDraw pid [") + std::to_string(getpid()) +
- "]");
+ // TODO: try to reduce the size of the buffer: possibly by using clip bounds.
+ static_cast<uint32_t>(surfaceInfo.width()),
+ static_cast<uint32_t>(surfaceInfo.height()),
+ ColorTypeToPixelFormat(surfaceInfo.colorType()),
+ GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER |
+ GraphicBuffer::USAGE_SW_READ_NEVER | GraphicBuffer::USAGE_HW_RENDER,
+ std::string("VkInteropFunctorDrawable::onDraw pid [") + std::to_string(getpid()) +
+ "]");
status_t error = mFrameBuffer->initCheck();
if (error < 0) {
ALOGW("VkInteropFunctorDrawable::onDraw() failed in GraphicBuffer.create()");
@@ -110,16 +109,15 @@
mFBInfo = surfaceInfo;
}
- //TODO: Synchronization is needed on mFrameBuffer to guarantee that the previous Vulkan
- //TODO: draw command has completed.
- //TODO: A simple but inefficient way is to flush and issue a QueueWaitIdle call. See
- //TODO: GrVkGpu::destroyResources() for example.
+ // TODO: Synchronization is needed on mFrameBuffer to guarantee that the previous Vulkan
+ // TODO: draw command has completed.
+ // TODO: A simple but inefficient way is to flush and issue a QueueWaitIdle call. See
+ // TODO: GrVkGpu::destroyResources() for example.
bool success = sGLDrawThread->queue().runSync([&]() -> bool {
ATRACE_FORMAT("WebViewDraw_%dx%d", mFBInfo.width(), mFBInfo.height());
EGLDisplay display = sEglManager.eglDisplay();
- LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
- "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
- uirenderer::renderthread::EglManager::eglErrorString());
+ LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY, "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+ uirenderer::renderthread::EglManager::eglErrorString());
// We use an EGLImage to access the content of the GraphicBuffer
// The EGL image is later bound to a 2D texture
EGLClientBuffer clientBuffer = (EGLClientBuffer)mFrameBuffer->getNativeBuffer();
@@ -154,10 +152,10 @@
AutoGLFramebuffer glFb;
// Bind texture to the frame buffer.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- glTexture.mTexture, 0);
+ glTexture.mTexture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
ALOGE("Failed framebuffer check for created target buffer: %s",
- GLUtils::getGLFramebufferError());
+ GLUtils::getGLFramebufferError());
return false;
}
@@ -166,19 +164,22 @@
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
- (*mFunctor)(DrawGlInfo::kModeDraw, &info);
+ if (mAnyFunctor.index() == 0) {
+ std::get<0>(mAnyFunctor).handle->drawGl(info);
+ } else {
+ (*(std::get<1>(mAnyFunctor).functor))(DrawGlInfo::kModeDraw, &info);
+ }
EGLSyncKHR glDrawFinishedFence =
eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_FENCE_KHR, NULL);
LOG_ALWAYS_FATAL_IF(glDrawFinishedFence == EGL_NO_SYNC_KHR,
- "Could not create sync fence %#x", eglGetError());
+ "Could not create sync fence %#x", eglGetError());
glFlush();
// TODO: export EGLSyncKHR in file descr
// TODO: import file desc in Vulkan Semaphore
// TODO: instead block the GPU: probably by using external Vulkan semaphore.
// Block the CPU until the glFlush finish.
- EGLint waitStatus = eglClientWaitSyncKHR(display, glDrawFinishedFence, 0,
- FENCE_TIMEOUT);
+ EGLint waitStatus = eglClientWaitSyncKHR(display, glDrawFinishedFence, 0, FENCE_TIMEOUT);
LOG_ALWAYS_FATAL_IF(waitStatus != EGL_CONDITION_SATISFIED_KHR,
"Failed to wait for the fence %#x", eglGetError());
eglDestroySyncKHR(display, glDrawFinishedFence);
@@ -197,26 +198,25 @@
canvas->resetMatrix();
auto functorImage = SkImage::MakeFromAHardwareBuffer(
- reinterpret_cast<AHardwareBuffer*>(mFrameBuffer.get()), kPremul_SkAlphaType,
- nullptr, kBottomLeft_GrSurfaceOrigin);
+ reinterpret_cast<AHardwareBuffer*>(mFrameBuffer.get()), kPremul_SkAlphaType, nullptr,
+ kBottomLeft_GrSurfaceOrigin);
canvas->drawImage(functorImage, 0, 0, &paint);
canvas->restore();
}
VkInteropFunctorDrawable::~VkInteropFunctorDrawable() {
- if (mListener.get() != nullptr) {
- ScopedDrawRequest _drawRequest{};
- sGLDrawThread->queue().runSync([&]() {
- mListener->onGlFunctorReleased(mFunctor);
- });
+ if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
+ if (lp->listener) {
+ ScopedDrawRequest _drawRequest{};
+ sGLDrawThread->queue().runSync(
+ [&]() { lp->listener->onGlFunctorReleased(lp->functor); });
+ }
}
}
-void VkInteropFunctorDrawable::syncFunctor() const {
+void VkInteropFunctorDrawable::syncFunctor(const WebViewSyncData& data) const {
ScopedDrawRequest _drawRequest{};
- sGLDrawThread->queue().runSync([&]() {
- (*mFunctor)(DrawGlInfo::kModeSync, nullptr);
- });
+ sGLDrawThread->queue().runSync([&]() { FunctorDrawable::syncFunctor(data); });
}
} // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
index 8fe52c5..c47ee11 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
@@ -18,8 +18,8 @@
#include "FunctorDrawable.h"
-#include <utils/RefBase.h>
#include <ui/GraphicBuffer.h>
+#include <utils/RefBase.h>
namespace android {
namespace uirenderer {
@@ -32,20 +32,18 @@
*/
class VkInteropFunctorDrawable : public FunctorDrawable {
public:
- VkInteropFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener,
- SkCanvas* canvas)
- : FunctorDrawable(functor, listener, canvas) {}
+ using FunctorDrawable::FunctorDrawable;
+
virtual ~VkInteropFunctorDrawable();
- void syncFunctor() const override;
-
static void vkInvokeFunctor(Functor* functor);
+ void syncFunctor(const WebViewSyncData& data) const override;
+
protected:
virtual void onDraw(SkCanvas* canvas) override;
private:
-
// Variables below describe/store temporary offscreen buffer used for Vulkan pipeline.
sp<GraphicBuffer> mFrameBuffer;
SkImageInfo mFBInfo;