Break Layer class into Gl and Vulkan subclasses
Test: manual testing
Change-Id: Ibd2beed39de3ac6da7448e96496253cfe427dfbb
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 18e59e5..f24c1fb 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -75,6 +75,7 @@
FrameInfo.cpp \
FrameInfoVisualizer.cpp \
GammaFontRenderer.cpp \
+ GlLayer.cpp \
GlopBuilder.cpp \
GpuMemoryTracker.cpp \
GradientCache.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index b463e45..a0366de 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -17,7 +17,7 @@
#include "Caches.h"
#include "GammaFontRenderer.h"
-#include "Layer.h"
+#include "GlLayer.h"
#include "Properties.h"
#include "renderstate/RenderState.h"
#include "ShadowTessellator.h"
@@ -170,9 +170,11 @@
for (std::set<Layer*>::iterator it = mRenderState->mActiveLayers.begin();
it != mRenderState->mActiveLayers.end(); it++) {
const Layer* layer = *it;
- log.appendFormat(" Layer size %dx%d; texid=%u refs=%d\n",
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL);
+ const GlLayer* glLayer = static_cast<const GlLayer*>(layer);
+ log.appendFormat(" GlLayer size %dx%d; texid=%u refs=%d\n",
layer->getWidth(), layer->getHeight(),
- layer->getTextureId(),
+ glLayer->getTextureId(),
layer->getStrongCount());
memused += layer->getWidth() * layer->getHeight() * 4;
}
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index a7d5f60..21aa6e1 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -15,6 +15,7 @@
*/
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
#include "renderthread/EglManager.h"
#include "renderthread/RenderTask.h"
#include "utils/PaintUtils.h"
@@ -55,9 +56,12 @@
mLayer->setAlpha(mAlpha, mMode);
if (mSurfaceTexture.get()) {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "apply surfaceTexture with non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
if (mNeedsGLContextAttach) {
mNeedsGLContextAttach = false;
- mSurfaceTexture->attachToContext(mLayer->getTextureId());
+ mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());
}
if (mUpdateTexImage) {
mUpdateTexImage = false;
@@ -71,6 +75,9 @@
}
void DeferredLayerUpdater::doUpdateTexImage() {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "doUpdateTexImage non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
float transform[16];
@@ -112,28 +119,36 @@
void DeferredLayerUpdater::updateLayer(bool forceFilter, GLenum renderTarget,
const float* textureTransform) {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "updateLayer non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
+
mLayer->setBlend(mBlend);
mLayer->setForceFilter(forceFilter);
mLayer->setSize(mWidth, mHeight);
mLayer->getTexTransform().load(textureTransform);
- if (renderTarget != mLayer->getRenderTarget()) {
- mLayer->setRenderTarget(renderTarget);
- mLayer->bindTexture();
- mLayer->setFilter(GL_NEAREST, false, true);
- mLayer->setWrap(GL_CLAMP_TO_EDGE, false, true);
+ GlLayer* glLayer = static_cast<GlLayer*>(mLayer);
+ if (renderTarget != glLayer->getRenderTarget()) {
+ glLayer->setRenderTarget(renderTarget);
+ glLayer->bindTexture();
+ glLayer->setFilter(GL_NEAREST, false, true);
+ glLayer->setWrap(GL_CLAMP_TO_EDGE, false, true);
}
}
void DeferredLayerUpdater::detachSurfaceTexture() {
if (mSurfaceTexture.get()) {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "detachSurfaceTexture with non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
status_t err = mSurfaceTexture->detachFromContext();
if (err != 0) {
// TODO: Elevate to fatal exception
ALOGE("Failed to detach SurfaceTexture from context %d", err);
}
mSurfaceTexture = nullptr;
- mLayer->clearTexture();
+ static_cast<GlLayer*>(mLayer)->clearTexture();
}
}
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 7335008..9be415f 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -22,6 +22,9 @@
#include <SkMatrix.h>
#include <utils/StrongPointer.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
#include "Layer.h"
#include "Rect.h"
#include "renderthread/RenderThread.h"
@@ -60,8 +63,8 @@
ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture, bool needsAttach) {
if (texture.get() != mSurfaceTexture.get()) {
- mNeedsGLContextAttach = needsAttach;
mSurfaceTexture = texture;
+ mNeedsGLContextAttach = needsAttach;
GLenum target = texture->getCurrentTextureTarget();
LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
new file mode 100644
index 0000000..c0ab895
--- /dev/null
+++ b/libs/hwui/GlLayer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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 "GlLayer.h"
+
+#include "Caches.h"
+#include "RenderNode.h"
+#include "renderstate/RenderState.h"
+#include "utils/TraceUtils.h"
+
+#include <utils/Log.h>
+
+#define ATRACE_LAYER_WORK(label) \
+ ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \
+ label, \
+ (renderNode.get() != NULL) ? renderNode->getName() : "", \
+ getWidth(), getHeight())
+
+namespace android {
+namespace uirenderer {
+
+GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+ : Layer(renderState, Api::OpenGL)
+ , caches(Caches::getInstance())
+ , texture(caches) {
+ texture.mWidth = layerWidth;
+ texture.mHeight = layerHeight;
+}
+
+GlLayer::~GlLayer() {
+ if (texture.mId) {
+ texture.deleteTexture();
+ }
+}
+
+void GlLayer::onGlContextLost() {
+ texture.deleteTexture();
+}
+
+void GlLayer::bindTexture() const {
+ if (texture.mId) {
+ caches.textureState().bindTexture(texture.target(), texture.mId);
+ }
+}
+
+void GlLayer::generateTexture() {
+ if (!texture.mId) {
+ glGenTextures(1, &texture.mId);
+ }
+}
+
+void GlLayer::clearTexture() {
+ // There's a rare possibility that Caches could have been destroyed already
+ // since this method is queued up as a task.
+ // Since this is a reset method, treat this as non-fatal.
+ if (caches.isInitialized()) {
+ caches.textureState().unbindTexture(texture.mId);
+ }
+ texture.mId = 0;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
new file mode 100644
index 0000000..54bf5ad
--- /dev/null
+++ b/libs/hwui/GlLayer.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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 "Layer.h"
+
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+// Forward declarations
+class Caches;
+
+/**
+ * A layer has dimensions and is backed by an OpenGL texture or FBO.
+ */
+class GlLayer : public Layer {
+public:
+ GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+ virtual ~GlLayer();
+
+ uint32_t getWidth() const override {
+ return texture.mWidth;
+ }
+
+ uint32_t getHeight() const override {
+ return texture.mHeight;
+ }
+
+ void setSize(uint32_t width, uint32_t height) override {
+ texture.updateSize(width, height, texture.internalFormat(), texture.format(),
+ texture.target());
+ }
+
+ void setBlend(bool blend) override {
+ texture.blend = blend;
+ }
+
+ bool isBlend() const override {
+ return texture.blend;
+ }
+
+ inline GLuint getTextureId() const {
+ return texture.id();
+ }
+
+ inline Texture& getTexture() {
+ return texture;
+ }
+
+ inline GLenum getRenderTarget() const {
+ return texture.target();
+ }
+
+ inline void setRenderTarget(GLenum renderTarget) {
+ texture.mTarget = renderTarget;
+ }
+
+ inline bool isRenderable() const {
+ return texture.target() != GL_NONE;
+ }
+
+ void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
+ texture.setWrap(wrap, bindTexture, force);
+ }
+
+ void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
+ texture.setFilter(filter, bindTexture, force);
+ }
+
+ void bindTexture() const;
+ void generateTexture();
+
+ /**
+ * When the caller frees the texture itself, the caller
+ * must call this method to tell this layer that it lost
+ * the texture.
+ */
+ void clearTexture();
+
+ /**
+ * Lost the GL context but the layer is still around, mark it invalid internally
+ * so the dtor knows not to do any GL work
+ */
+ void onGlContextLost();
+
+private:
+ Caches& caches;
+
+ /**
+ * The texture backing this layer.
+ */
+ Texture texture;
+}; // struct GlLayer
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 34e6d39..8a6e038 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -16,6 +16,7 @@
#include "GlopBuilder.h"
#include "Caches.h"
+#include "GlLayer.h"
#include "Glop.h"
#include "Layer.h"
#include "Matrix.h"
@@ -440,7 +441,7 @@
return *this;
}
-GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) {
+GlopBuilder& GlopBuilder::setFillTextureLayer(GlLayer& layer, float alpha) {
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 8a8b652..87b1568 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -28,6 +28,7 @@
namespace uirenderer {
class Caches;
+class GlLayer;
class Matrix4;
class Patch;
class RenderState;
@@ -71,7 +72,7 @@
GlopBuilder& setFillClear();
GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
float alpha, SkBlendMode mode, Blend::ModeOrderSwap modeUsage);
- GlopBuilder& setFillTextureLayer(Layer& layer, float alpha);
+ GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
// TODO: setFillLayer normally forces its own wrap & filter mode,
// which isn't always correct.
GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 88817ef..331bb81 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -16,77 +16,36 @@
#include "Layer.h"
-#include "Caches.h"
-#include "RenderNode.h"
#include "renderstate/RenderState.h"
-#include "utils/TraceUtils.h"
-#include <utils/Log.h>
-
-#define ATRACE_LAYER_WORK(label) \
- ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \
- label, \
- (renderNode.get() != NULL) ? renderNode->getName() : "", \
- getWidth(), getHeight())
+#include <SkColorFilter.h>
namespace android {
namespace uirenderer {
-Layer::Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+Layer::Layer(RenderState& renderState, Api api)
: GpuMemoryTracker(GpuObjectType::Layer)
- , state(State::Uncached)
- , caches(Caches::getInstance())
- , renderState(renderState)
- , texture(caches) {
+ , mRenderState(renderState)
+ , mApi(api) {
// TODO: This is a violation of Android's typical ref counting, but it
// preserves the old inc/dec ref locations. This should be changed...
incStrong(nullptr);
- texture.mWidth = layerWidth;
- texture.mHeight = layerHeight;
+
renderState.registerLayer(this);
}
Layer::~Layer() {
- renderState.unregisterLayer(this);
SkSafeUnref(colorFilter);
- if (texture.mId) {
- texture.deleteTexture();
- }
-}
-
-void Layer::onGlContextLost() {
- texture.deleteTexture();
+ mRenderState.unregisterLayer(this);
}
void Layer::setColorFilter(SkColorFilter* filter) {
SkRefCnt_SafeAssign(colorFilter, filter);
}
-void Layer::bindTexture() const {
- if (texture.mId) {
- caches.textureState().bindTexture(texture.target(), texture.mId);
- }
-}
-
-void Layer::generateTexture() {
- if (!texture.mId) {
- glGenTextures(1, &texture.mId);
- }
-}
-
-void Layer::clearTexture() {
- // There's a rare possibility that Caches could have been destroyed already
- // since this method is queued up as a task.
- // Since this is a reset method, treat this as non-fatal.
- if (caches.isInitialized()) {
- caches.textureState().unbindTexture(texture.mId);
- }
- texture.mId = 0;
-}
-
void Layer::postDecStrong() {
- renderState.postDecStrong(this);
+ mRenderState.postDecStrong(this);
}
}; // namespace uirenderer
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 8e71cd1..3b639ee 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -16,25 +16,13 @@
#pragma once
-#include <cutils/compiler.h>
-#include <sys/types.h>
-#include <utils/StrongPointer.h>
#include <utils/RefBase.h>
-#include <memory>
-
-#include <GLES2/gl2.h>
#include <GpuMemoryTracker.h>
-#include <ui/Region.h>
-
#include <SkPaint.h>
#include <SkBlendMode.h>
#include "Matrix.h"
-#include "Rect.h"
-#include "RenderBuffer.h"
-#include "Texture.h"
-#include "Vertex.h"
namespace android {
namespace uirenderer {
@@ -43,49 +31,33 @@
// Layers
///////////////////////////////////////////////////////////////////////////////
-// Forward declarations
-class Caches;
class RenderState;
/**
- * A layer has dimensions and is backed by an OpenGL texture or FBO.
+ * A layer has dimensions and is backed by a backend specific texture or framebuffer.
*/
class Layer : public VirtualLightRefBase, GpuMemoryTracker {
public:
- // layer lifecycle, controlled from outside
- enum class State {
- Uncached = 0,
- InCache = 1,
- FailedToCache = 2,
- RemovedFromCache = 3,
- DeletedFromCache = 4,
- InGarbageList = 5,
+ enum class Api {
+ OpenGL = 0,
+ Vulkan = 1,
};
- State state; // public for logging/debugging purposes
- Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+ Api getApi() const {
+ return mApi;
+ }
+
~Layer();
- inline uint32_t getWidth() const {
- return texture.mWidth;
- }
+ virtual uint32_t getWidth() const = 0;
- inline uint32_t getHeight() const {
- return texture.mHeight;
- }
+ virtual uint32_t getHeight() const = 0;
- void setSize(uint32_t width, uint32_t height) {
- texture.updateSize(width, height, texture.internalFormat(), texture.format(),
- texture.target());
- }
+ virtual void setSize(uint32_t width, uint32_t height) = 0;
- inline void setBlend(bool blend) {
- texture.blend = blend;
- }
+ virtual void setBlend(bool blend) = 0;
- inline bool isBlend() const {
- return texture.blend;
- }
+ virtual bool isBlend() const = 0;
inline void setForceFilter(bool forceFilter) {
this->forceFilter = forceFilter;
@@ -112,50 +84,12 @@
return mode;
}
- inline GLuint getTextureId() const {
- return texture.id();
- }
-
- inline Texture& getTexture() {
- return texture;
- }
-
- inline GLenum getRenderTarget() const {
- return texture.target();
- }
-
- inline void setRenderTarget(GLenum renderTarget) {
- texture.mTarget = renderTarget;
- }
-
- inline bool isRenderable() const {
- return texture.target() != GL_NONE;
- }
-
- void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
- texture.setWrap(wrap, bindTexture, force);
- }
-
- void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
- texture.setFilter(filter, bindTexture, force);
- }
-
inline SkColorFilter* getColorFilter() const {
return colorFilter;
}
void setColorFilter(SkColorFilter* filter);
- void bindTexture() const;
- void generateTexture();
-
- /**
- * When the caller frees the texture itself, the caller
- * must call this method to tell this layer that it lost
- * the texture.
- */
- void clearTexture();
-
inline mat4& getTexTransform() {
return texTransform;
}
@@ -170,21 +104,13 @@
*/
void postDecStrong();
- /**
- * Lost the GL context but the layer is still around, mark it invalid internally
- * so the dtor knows not to do any GL work
- */
- void onGlContextLost();
+protected:
+ Layer(RenderState& renderState, Api api);
+
+ RenderState& mRenderState;
private:
- Caches& caches;
-
- RenderState& renderState;
-
- /**
- * The texture backing this layer.
- */
- Texture texture;
+ Api mApi;
/**
* Color filter used to draw this layer. Optional.
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index 938b6ef..c460c0d 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -19,7 +19,7 @@
#include "Caches.h"
#include "Image.h"
#include "GlopBuilder.h"
-#include "Layer.h"
+#include "GlLayer.h"
#include "renderstate/RenderState.h"
#include "renderthread/EglManager.h"
#include "utils/GLUtils.h"
@@ -262,7 +262,7 @@
}
bool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread,
- Layer& layer, SkBitmap* bitmap) {
+ GlLayer& layer, SkBitmap* bitmap) {
return CopyResult::Success == copyTextureInto(Caches::getInstance(),
renderThread.renderState(), layer.getTexture(), layer.getTexTransform(),
Rect(), bitmap);
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index f4ebabc..c9222cf 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -22,7 +22,7 @@
namespace uirenderer {
class Matrix4;
-class Layer;
+class GlLayer;
class OpenGLReadback : public Readback {
public:
@@ -49,7 +49,7 @@
/**
* Copies the layer's contents into the provided bitmap.
*/
- static bool copyLayerInto(renderthread::RenderThread& renderThread, Layer& layer,
+ static bool copyLayerInto(renderthread::RenderThread& renderThread, GlLayer& layer,
SkBitmap* bitmap);
protected:
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index f9a7c36f2..dea2be6 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -17,6 +17,7 @@
#pragma once
#include "font/FontUtil.h"
+#include "GlLayer.h"
#include "Matrix.h"
#include "Rect.h"
#include "RenderNode.h"
@@ -413,7 +414,7 @@
};
struct TextureLayerOp : RecordedOp {
- TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer)
+ TextureLayerOp(BASE_PARAMS_PAINTLESS, GlLayer* layer)
: SUPER_PAINTLESS(TextureLayerOp)
, layer(layer) {}
@@ -424,7 +425,7 @@
, layer(op.layer) {
}
- Layer* layer;
+ GlLayer* layer;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index ee6279d..b5e5d68 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -606,13 +606,14 @@
// We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics.
mDisplayList->ref(layerHandle);
+ LOG_ALWAYS_FATAL_IF(layerHandle->backingLayer()->getApi() != Layer::Api::OpenGL);
// Note that the backing layer has *not* yet been updated, so don't trust
// its width, height, transform, etc...!
addOp(alloc().create_trivial<TextureLayerOp>(
Rect(layerHandle->getWidth(), layerHandle->getHeight()),
*(mState.currentSnapshot()->transform),
getRecordedClip(),
- layerHandle->backingLayer()));
+ static_cast<GlLayer*>(layerHandle->backingLayer())));
}
void RecordingCanvas::callDrawGLFunction(Functor* functor,
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index fadb960..9239986 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -18,7 +18,6 @@
#include "Caches.h"
#include "Extensions.h"
-#include "Layer.h"
#include "Matrix.h"
#include "Texture.h"
#include "hwui/Bitmap.h"
@@ -317,42 +316,6 @@
return true;
}
-bool tryStoreLayer(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
- GLuint* textureUnit, ProgramDescription* description,
- SkiaShaderData::LayerShaderData* outData) {
- Layer* layer;
- if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) {
- return false;
- }
-
- description->hasBitmap = true;
- outData->layer = layer;
- outData->bitmapSampler = (*textureUnit)++;
-
- const float width = layer->getWidth();
- const float height = layer->getHeight();
-
- computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(),
- modelViewMatrix);
-
- outData->textureDimension[0] = 1.0f / width;
- outData->textureDimension[1] = 1.0f / height;
- return true;
-}
-
-void applyLayer(Caches& caches, const SkiaShaderData::LayerShaderData& data) {
- caches.textureState().activateTexture(data.bitmapSampler);
-
- data.layer->bindTexture();
- data.layer->setWrap(GL_CLAMP_TO_EDGE);
- data.layer->setFilter(GL_LINEAR);
-
- glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler);
- glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1,
- GL_FALSE, &data.textureTransform.data[0]);
- glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]);
-}
-
void SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
GLuint* textureUnit, ProgramDescription* description,
SkiaShaderData* outData) {
@@ -374,12 +337,6 @@
return;
}
- if (tryStoreLayer(caches, shader, modelViewMatrix,
- textureUnit, description, &outData->layerData)) {
- outData->skiaShaderType = kLayer_SkiaShaderType;
- return;
- }
-
// Unknown/unsupported type, so explicitly ignore shader
outData->skiaShaderType = kNone_SkiaShaderType;
}
@@ -394,10 +351,6 @@
if (data.skiaShaderType & kBitmap_SkiaShaderType) {
applyBitmap(caches, data.bitmapData);
}
-
- if (data.skiaShaderType == kLayer_SkiaShaderType) {
- applyLayer(caches, data.layerData);
- }
}
}; // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index d2f37cd..ab578d5 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -29,7 +29,6 @@
class Caches;
class Extensions;
-class Layer;
class Texture;
struct ProgramDescription;
@@ -45,7 +44,6 @@
kBitmap_SkiaShaderType = 1,
kGradient_SkiaShaderType = 2,
kCompose_SkiaShaderType = kBitmap_SkiaShaderType | kGradient_SkiaShaderType,
- kLayer_SkiaShaderType = 4,
};
struct SkiaShaderData {
@@ -71,15 +69,6 @@
GLuint gradientSampler;
GLenum wrapST;
} gradientData;
- struct LayerShaderData {
- Layer* layer;
- GLuint bitmapSampler;
- GLenum wrapS;
- GLenum wrapT;
-
- Matrix4 textureTransform;
- float textureDimension[2];
- } layerData;
};
class SkiaShader {
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index c75e88f..b8397cc 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -159,10 +159,10 @@
*/
void* isInUse = nullptr;
private:
- // TODO: Temporarily grant private access to Layer, remove once
- // Layer can be de-tangled from being a dual-purpose render target
+ // TODO: Temporarily grant private access to GlLayer, remove once
+ // GlLayer can be de-tangled from being a dual-purpose render target
// and external texture wrapper
- friend class Layer;
+ friend class GlLayer;
// Returns true if the size changed, false if it was the same
bool updateSize(uint32_t width, uint32_t height, GLint internalFormat,
diff --git a/libs/hwui/VkLayer.h b/libs/hwui/VkLayer.h
new file mode 100644
index 0000000..353939f
--- /dev/null
+++ b/libs/hwui/VkLayer.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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 "Layer.h"
+
+#include <SkSurface.h>
+
+namespace android {
+namespace uirenderer {
+/**
+ * A layer has dimensions and is backed by a VkImage.
+ */
+class VkLayer : public Layer {
+public:
+ VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+ : Layer(renderState, Api::Vulkan) {}
+
+ virtual ~VkLayer() {}
+
+ uint32_t getWidth() const override {
+ return mWidth;
+ }
+
+ uint32_t getHeight() const override {
+ return mHeight;
+ }
+
+ void setSize(uint32_t width, uint32_t height) override {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ void setBlend(bool blend) override {
+ mBlend = blend;
+ }
+
+ bool isBlend() const override {
+ return mBlend;
+ }
+
+ sk_sp<SkSurface> getSurface() {
+ return mSurface;
+ }
+
+private:
+ int mWidth;
+ int mHeight;
+ bool mBlend;
+
+ sk_sp<SkSurface> mSurface;
+
+}; // struct VkLayer
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index f2af4a8..05d28e4 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "GlLayer.h"
#include "LayerDrawable.h"
#include "SkColorFilter.h"
#include "gl/GrGLTypes.h"
@@ -35,12 +36,14 @@
layer->getTransform().copyTo(transform);
canvas->concat(transform);
}
+
+ GlLayer* glLayer = static_cast<GlLayer*>(layer);
GrGLTextureInfo externalTexture;
- externalTexture.fTarget = layer->getRenderTarget();
- externalTexture.fID = layer->getTextureId();
+ externalTexture.fTarget = glLayer->getRenderTarget();
+ externalTexture.fID = glLayer->getTextureId();
GrBackendTextureDesc textureDescription;
- textureDescription.fWidth = layer->getWidth();
- textureDescription.fHeight = layer->getHeight();
+ textureDescription.fWidth = glLayer->getWidth();
+ textureDescription.fHeight = glLayer->getHeight();
textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index c8258f7..65a1dc3 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -17,6 +17,7 @@
#include "SkiaOpenGLPipeline.h"
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
#include "LayerDrawable.h"
#include "renderthread/EglManager.h"
#include "renderthread/Frame.h"
@@ -136,7 +137,7 @@
DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
mEglManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+ GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
layer->generateTexture();
return new DeferredLayerUpdater(layer);
}
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 0d3f4ef..910c339 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -22,6 +22,7 @@
#include "renderstate/RenderState.h"
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"
+#include "VkLayer.h"
#include <SkSurface.h>
#include <SkTypes.h>
@@ -119,7 +120,8 @@
DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
mVkManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+
+ VkLayer* layer = new VkLayer(mRenderThread.renderState(), 0, 0);
return new DeferredLayerUpdater(layer);
}
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 72af7c9..a23e676 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "GlLayer.h"
#include <GpuMemoryTracker.h>
#include "renderstate/RenderState.h"
@@ -55,7 +56,9 @@
}
static void layerLostGlContext(Layer* layer) {
- layer->onGlContextLost();
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL,
+ "layerLostGlContext on non GL layer");
+ static_cast<GlLayer*>(layer)->onGlContextLost();
}
void RenderState::onGLContextDestroyed() {
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index df08599..df40a44 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -19,6 +19,7 @@
#include "DeferredLayerUpdater.h"
#include "EglManager.h"
#include "Frame.h"
+#include "GlLayer.h"
#include "ProfileRenderer.h"
#include "renderstate/RenderState.h"
#include "OpenGLReadback.h"
@@ -120,12 +121,13 @@
bool OpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
ATRACE_CALL();
layer->apply();
- return OpenGLReadbackImpl::copyLayerInto(mRenderThread, *(layer->backingLayer()), bitmap);
+ return OpenGLReadbackImpl::copyLayerInto(mRenderThread,
+ static_cast<GlLayer&>(*layer->backingLayer()), bitmap);
}
DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
mEglManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+ GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
Caches::getInstance().textureState().activateTexture(0);
layer->generateTexture();
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index 0326aa9..f1b8882 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -15,6 +15,7 @@
*/
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
#include "renderthread/OpenGLPipeline.h"
#include "tests/common/TestUtils.h"
@@ -32,7 +33,10 @@
// updates are deferred so the backing layer should still be in its default state
- EXPECT_EQ((uint32_t)GL_NONE, layerUpdater->backingLayer()->getRenderTarget());
+ if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ EXPECT_EQ((uint32_t)GL_NONE, glLayer->getRenderTarget());
+ }
EXPECT_EQ(0u, layerUpdater->backingLayer()->getWidth());
EXPECT_EQ(0u, layerUpdater->backingLayer()->getHeight());
EXPECT_FALSE(layerUpdater->backingLayer()->getForceFilter());
@@ -45,7 +49,10 @@
layerUpdater->updateLayer(true, GL_TEXTURE_EXTERNAL_OES, scaledMatrix.data);
// the backing layer should now have all the properties applied.
- EXPECT_EQ((uint32_t)GL_TEXTURE_EXTERNAL_OES, layerUpdater->backingLayer()->getRenderTarget());
+ if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ EXPECT_EQ((uint32_t)GL_TEXTURE_EXTERNAL_OES, glLayer->getRenderTarget());
+ }
EXPECT_EQ(100u, layerUpdater->backingLayer()->getWidth());
EXPECT_EQ(100u, layerUpdater->backingLayer()->getHeight());
EXPECT_TRUE(layerUpdater->backingLayer()->getForceFilter());
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 21394ae..71c7516 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -19,6 +19,7 @@
#include <BakedOpState.h>
#include <DeferredLayerUpdater.h>
#include <FrameBuilder.h>
+#include <GlLayer.h>
#include <LayerUpdateQueue.h>
#include <RecordedOp.h>
#include <RecordingCanvas.h>
@@ -698,7 +699,10 @@
RENDERTHREAD_TEST(FrameBuilder, textureLayer_reject) {
auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
SkMatrix::MakeTrans(5, 5));
- layerUpdater->backingLayer()->setRenderTarget(GL_NONE); // Should be rejected
+ if (layerUpdater->backingLayer()->getApi() != Layer::Api::OpenGL) return;
+
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ glLayer->setRenderTarget(GL_NONE); // Should be rejected
auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
[&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {