diff options
author | 2017-01-09 14:15:41 -0500 | |
---|---|---|
committer | 2017-01-10 15:05:07 -0500 | |
commit | 8cd3edfa15cc9cdbffa935d19ab894426b08d174 (patch) | |
tree | 289ec13531b91be5adf6306d8d70434bc756b2c1 | |
parent | d14cafc27255e0ed44665a0975a57c487b841ab1 (diff) |
Break Layer class into Gl and Vulkan subclasses
Test: manual testing
Change-Id: Ibd2beed39de3ac6da7448e96496253cfe427dfbb
25 files changed, 365 insertions, 233 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 18e59e551845..f24c1fb7c06d 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -75,6 +75,7 @@ hwui_src_files := \ 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 b463e45fb39b..a0366dee3218 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 @@ void Caches::dumpMemoryUsage(String8 &log) { 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 a7d5f6026d00..21aa6e1f5705 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 @@ void DeferredLayerUpdater::apply() { 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::apply() { } 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::doUpdateTexImage() { 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 733500885e67..9be415f4d216 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 @@ public: 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 000000000000..c0ab895260ab --- /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 000000000000..54bf5adc3ace --- /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 34e6d39c9104..8a6e038d8e0d 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 @@ GlopBuilder& GlopBuilder::setFillLayer(Texture& texture, const SkColorFilter* co 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 8a8b652c393c..87b1568ed72b 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -28,6 +28,7 @@ namespace android { namespace uirenderer { class Caches; +class GlLayer; class Matrix4; class Patch; class RenderState; @@ -71,7 +72,7 @@ public: 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 88817efa80ac..331bb81208b1 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 8e71cd11599d..3b639ee49334 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 @@ namespace uirenderer { // 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 @@ public: 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 @@ public: */ 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(); - -private: - Caches& caches; +protected: + Layer(RenderState& renderState, Api api); - RenderState& renderState; + RenderState& mRenderState; - /** - * The texture backing this layer. - */ - Texture texture; +private: + Api mApi; /** * Color filter used to draw this layer. Optional. diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp index 938b6efa7901..c460c0d2dfd4 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 @@ CopyResult OpenGLReadbackImpl::copyImageInto(EGLImageKHR eglImage, } 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 f4ebabcdebe5..c9222cff51da 100644 --- a/libs/hwui/OpenGLReadback.h +++ b/libs/hwui/OpenGLReadback.h @@ -22,7 +22,7 @@ namespace android { namespace uirenderer { class Matrix4; -class Layer; +class GlLayer; class OpenGLReadback : public Readback { public: @@ -49,7 +49,7 @@ public: /** * 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 f9a7c36f2786..dea2be68c8db 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 TextOnPathOp : RecordedOp { }; struct TextureLayerOp : RecordedOp { - TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer) + TextureLayerOp(BASE_PARAMS_PAINTLESS, GlLayer* layer) : SUPER_PAINTLESS(TextureLayerOp) , layer(layer) {} @@ -424,7 +425,7 @@ struct TextureLayerOp : RecordedOp { , layer(op.layer) { } - Layer* layer; + GlLayer* layer; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index ee6279dccb92..b5e5d6801f99 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -606,13 +606,14 @@ void RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) { // 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 fadb96065105..92399864ff23 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 @@ bool tryStoreCompose(Caches& caches, const SkShader& shader, const Matrix4& mode 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 @@ void SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& mo 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 @@ void SkiaShader::apply(Caches& caches, const SkiaShaderData& data, 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 d2f37cda9cb3..ab578d540774 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -29,7 +29,6 @@ namespace uirenderer { class Caches; class Extensions; -class Layer; class Texture; struct ProgramDescription; @@ -45,7 +44,6 @@ enum SkiaShaderType { kBitmap_SkiaShaderType = 1, kGradient_SkiaShaderType = 2, kCompose_SkiaShaderType = kBitmap_SkiaShaderType | kGradient_SkiaShaderType, - kLayer_SkiaShaderType = 4, }; struct SkiaShaderData { @@ -71,15 +69,6 @@ struct SkiaShaderData { 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 c75e88f5dd6e..b8397ccade9c 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -159,10 +159,10 @@ public: */ 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 000000000000..353939f73b69 --- /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 f2af4a891b12..05d28e40f71c 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 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer 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 c8258f748d7e..65a1dc38ab8e 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 @@ bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBi 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 0d3f4ef6a11a..910c339c4d1c 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 @@ bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bi 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 72af7c98e477..a23e676ea996 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 @@ void RenderState::onGLContextCreated() { } 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 df085998435b..df40a44a16cb 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::swapBuffers(const Frame& frame, bool drew, const SkRect& sc 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 0326aa91bb18..f1b888268fde 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 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { // 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 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { 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 21394ae6144a..71c7516be3ba 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_combineMatrices) { 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) { |