remove BakedOps and much of renderstate
Test: make
Change-Id: If070b7436b848c6840abfac5f051b0f5b6cb17ce
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 6de3a38..f3cd3de 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -170,13 +170,9 @@
"pipeline/skia/SkiaRecordingCanvas.cpp",
"pipeline/skia/SkiaVulkanPipeline.cpp",
"pipeline/skia/VectorDrawableAtlas.cpp",
- "renderstate/Blend.cpp",
- "renderstate/MeshState.cpp",
"renderstate/OffscreenBufferPool.cpp",
"renderstate/PixelBufferState.cpp",
"renderstate/RenderState.cpp",
- "renderstate/Scissor.cpp",
- "renderstate/Stencil.cpp",
"renderstate/TextureState.cpp",
"renderthread/CacheManager.cpp",
"renderthread/CanvasContext.cpp",
@@ -200,9 +196,6 @@
"AnimationContext.cpp",
"Animator.cpp",
"AnimatorManager.cpp",
- "BakedOpDispatcher.cpp",
- "BakedOpRenderer.cpp",
- "BakedOpState.cpp",
"Caches.cpp",
"CanvasState.cpp",
"ClipArea.cpp",
@@ -212,13 +205,11 @@
"FrameInfo.cpp",
"FrameInfoVisualizer.cpp",
"GlLayer.cpp",
- "GlopBuilder.cpp",
"GpuMemoryTracker.cpp",
"Image.cpp",
"Interpolator.cpp",
"JankTracker.cpp",
"Layer.cpp",
- "LayerBuilder.cpp",
"LayerUpdateQueue.cpp",
"Matrix.cpp",
"OpDumper.cpp",
@@ -229,7 +220,6 @@
"PixelBuffer.cpp",
"ProfileData.cpp",
"ProfileDataContainer.cpp",
- "ProfileRenderer.cpp",
"Program.cpp",
"Properties.cpp",
"PropertyValuesAnimatorSet.cpp",
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
deleted file mode 100644
index 1f931ed..0000000
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2015 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 "BakedOpDispatcher.h"
-
-#include "BakedOpRenderer.h"
-#include "Caches.h"
-#include "DeferredLayerUpdater.h"
-#include "Glop.h"
-#include "GlopBuilder.h"
-#include "Patch.h"
-#include "PathTessellator.h"
-#include "VertexBuffer.h"
-#include "renderstate/OffscreenBufferPool.h"
-#include "renderstate/RenderState.h"
-#include "utils/GLUtils.h"
-
-#include <SkPaintDefaults.h>
-#include <SkPathOps.h>
-#include <math.h>
-#include <algorithm>
-
-namespace android {
-namespace uirenderer {
-
-void BakedOpDispatcher::onMergedBitmapOps(BakedOpRenderer& renderer,
- const MergedBakedOpList& opList) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onMergedPatchOps(BakedOpRenderer& renderer,
- const MergedBakedOpList& opList) {
- // DEAD CODE
-}
-
-static void renderTextShadow(BakedOpRenderer& renderer, const TextOp& op,
- const BakedOpState& textOpState) {
- // DEAD CODE
-}
-
-enum class TextRenderType { Defer, Flush };
-
-static void renderText(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state,
- const ClipBase* renderClip, TextRenderType renderType) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
- const MergedBakedOpList& opList) {
- for (size_t i = 0; i < opList.count; i++) {
- const BakedOpState& state = *(opList.states[i]);
- const TextOp& op = *(static_cast<const TextOp*>(state.op));
- renderTextShadow(renderer, op, state);
- }
-
- ClipRect renderTargetClip(opList.clip);
- const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
- for (size_t i = 0; i < opList.count; i++) {
- const BakedOpState& state = *(opList.states[i]);
- const TextOp& op = *(static_cast<const TextOp*>(state.op));
- TextRenderType renderType =
- (i + 1 == opList.count) ? TextRenderType::Flush : TextRenderType::Defer;
- renderText(renderer, op, state, clip, renderType);
- }
-}
-
-namespace VertexBufferRenderFlags {
-enum {
- Offset = 0x1,
- ShadowInterp = 0x2,
-};
-}
-
-static void renderVertexBuffer(BakedOpRenderer& renderer, const BakedOpState& state,
- const VertexBuffer& vertexBuffer, float translateX, float translateY,
- const SkPaint& paint, int vertexBufferRenderFlags) {
- if (CC_LIKELY(vertexBuffer.getVertexCount())) {
- bool shadowInterp = vertexBufferRenderFlags & VertexBufferRenderFlags::ShadowInterp;
- const int transformFlags = vertexBufferRenderFlags & VertexBufferRenderFlags::Offset
- ? TransformFlags::OffsetByFudgeFactor
- : 0;
-
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshVertexBuffer(vertexBuffer)
- .setFillPaint(paint, state.alpha, shadowInterp)
- .setTransform(state.computedState.transform, transformFlags)
- .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
- .build();
- renderer.renderGlop(state, glop);
- }
-}
-
-SkRect getBoundsOfFill(const RecordedOp& op) {
- SkRect bounds = op.unmappedBounds.toSkRect();
- if (op.paint->getStyle() == SkPaint::kStrokeAndFill_Style) {
- float outsetDistance = op.paint->getStrokeWidth() / 2;
- bounds.outset(outsetDistance, outsetDistance);
- }
- return bounds;
-}
-
-void BakedOpDispatcher::onArcOp(BakedOpRenderer& renderer, const ArcOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op,
- const BakedOpState& state) {
- Texture* texture = renderer.getTexture(op.bitmap);
- if (!texture) return;
- const AutoTexture autoCleanup(texture);
-
- const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
- ? TextureFillFlags::IsAlphaMaskTexture
- : TextureFillFlags::None;
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedUnitQuad(texture->uvMapper)
- .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRectSnap(Rect(texture->width(), texture->height()))
- .build();
- renderer.renderGlop(state, glop);
-}
-
-void BakedOpDispatcher::onBitmapMeshOp(BakedOpRenderer& renderer, const BitmapMeshOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRectOp& op,
- const BakedOpState& state) {
- Texture* texture = renderer.getTexture(op.bitmap);
- if (!texture) return;
- const AutoTexture autoCleanup(texture);
-
- Rect uv(std::max(0.0f, op.src.left / texture->width()),
- std::max(0.0f, op.src.top / texture->height()),
- std::min(1.0f, op.src.right / texture->width()),
- std::min(1.0f, op.src.bottom / texture->height()));
-
- const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
- ? TextureFillFlags::IsAlphaMaskTexture
- : TextureFillFlags::None;
- const bool tryToSnap = MathUtils::areEqual(op.src.getWidth(), op.unmappedBounds.getWidth()) &&
- MathUtils::areEqual(op.src.getHeight(), op.unmappedBounds.getHeight());
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedUvQuad(texture->uvMapper, uv)
- .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRectOptionalSnap(tryToSnap, op.unmappedBounds)
- .build();
- renderer.renderGlop(state, glop);
-}
-
-void BakedOpDispatcher::onColorOp(BakedOpRenderer& renderer, const ColorOp& op,
- const BakedOpState& state) {
- SkPaint paint;
- paint.setColor(op.color);
- paint.setBlendMode(op.mode);
-
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshUnitQuad()
- .setFillPaint(paint, state.alpha)
- .setTransform(Matrix4::identity(), TransformFlags::None)
- .setModelViewMapUnitToRect(state.computedState.clipState->rect)
- .build();
- renderer.renderGlop(state, glop);
-}
-
-void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op,
- const BakedOpState& state) {
- renderer.renderFunctor(op, state);
-}
-
-void BakedOpDispatcher::onLinesOp(BakedOpRenderer& renderer, const LinesOp& op,
- const BakedOpState& state) {
- VertexBuffer buffer;
- PathTessellator::tessellateLines(op.points, op.floatCount, op.paint,
- state.computedState.transform, buffer);
- int displayFlags = op.paint->isAntiAlias() ? 0 : VertexBufferRenderFlags::Offset;
- renderVertexBuffer(renderer, state, buffer, 0, 0, *(op.paint), displayFlags);
-}
-
-void BakedOpDispatcher::onOvalOp(BakedOpRenderer& renderer, const OvalOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onPatchOp(BakedOpRenderer& renderer, const PatchOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onPathOp(BakedOpRenderer& renderer, const PathOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onPointsOp(BakedOpRenderer& renderer, const PointsOp& op,
- const BakedOpState& state) {
- VertexBuffer buffer;
- PathTessellator::tessellatePoints(op.points, op.floatCount, op.paint,
- state.computedState.transform, buffer);
- int displayFlags = op.paint->isAntiAlias() ? 0 : VertexBufferRenderFlags::Offset;
- renderVertexBuffer(renderer, state, buffer, 0, 0, *(op.paint), displayFlags);
-}
-
-// See SkPaintDefaults.h
-#define SkPaintDefaults_MiterLimit SkIntToScalar(4)
-
-void BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onRoundRectOp(BakedOpRenderer& renderer, const RoundRectOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleRectsOp& op,
- const BakedOpState& state) {
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshIndexedQuads(&op.vertices[0], op.vertexCount / 4)
- .setFillPaint(*op.paint, state.alpha)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewOffsetRect(0, 0, op.unmappedBounds)
- .build();
- renderer.renderGlop(state, glop);
-}
-
-void BakedOpDispatcher::onTextOp(BakedOpRenderer& renderer, const TextOp& op,
- const BakedOpState& state) {
- renderTextShadow(renderer, op, state);
- renderText(renderer, op, state, state.computedState.getClipIfNeeded(), TextRenderType::Flush);
-}
-
-void BakedOpDispatcher::onTextOnPathOp(BakedOpRenderer& renderer, const TextOnPathOp& op,
- const BakedOpState& state) {
- // DEAD CODE
-}
-
-void BakedOpDispatcher::onTextureLayerOp(BakedOpRenderer& renderer, const TextureLayerOp& op,
- const BakedOpState& state) {
- GlLayer* layer = static_cast<GlLayer*>(op.layerHandle->backingLayer());
- if (!layer) {
- return;
- }
- const bool tryToSnap = layer->getForceFilter();
- float alpha = (layer->getAlpha() / 255.0f) * state.alpha;
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO
- .setFillTextureLayer(*(layer), alpha)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRectOptionalSnap(tryToSnap,
- Rect(layer->getWidth(), layer->getHeight()))
- .build();
- renderer.renderGlop(state, glop);
-}
-
-void renderRectForLayer(BakedOpRenderer& renderer, const LayerOp& op, const BakedOpState& state,
- int color, SkBlendMode mode, SkColorFilter* colorFilter) {
- SkPaint paint;
- paint.setColor(color);
- paint.setBlendMode(mode);
- paint.setColorFilter(sk_ref_sp(colorFilter));
- RectOp rectOp(op.unmappedBounds, op.localMatrix, op.localClip, &paint);
- BakedOpDispatcher::onRectOp(renderer, rectOp, state);
-}
-
-void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op,
- const BakedOpState& state) {
- // Note that we don't use op->paint in this function - it's never set on a LayerOp
- OffscreenBuffer* buffer = *op.layerHandle;
-
- if (CC_UNLIKELY(!buffer)) return;
-
- float layerAlpha = op.alpha * state.alpha;
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedIndexedVbo(buffer->vbo, buffer->elementCount)
- .setFillLayer(buffer->texture, op.colorFilter, layerAlpha, op.mode,
- Blend::ModeOrderSwap::NoSwap)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewOffsetRectSnap(
- op.unmappedBounds.left, op.unmappedBounds.top,
- Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight()))
- .build();
- renderer.renderGlop(state, glop);
-
- if (!buffer->hasRenderedSinceRepaint) {
- buffer->hasRenderedSinceRepaint = true;
- if (CC_UNLIKELY(Properties::debugLayersUpdates)) {
- // render debug layer highlight
- renderRectForLayer(renderer, op, state, 0x7f00ff00, SkBlendMode::kSrcOver, nullptr);
- } else if (CC_UNLIKELY(Properties::debugOverdraw)) {
- // render transparent to increment overdraw for repaint area
- renderRectForLayer(renderer, op, state, SK_ColorTRANSPARENT, SkBlendMode::kSrcOver,
- nullptr);
- }
- }
-}
-
-void BakedOpDispatcher::onCopyToLayerOp(BakedOpRenderer& renderer, const CopyToLayerOp& op,
- const BakedOpState& state) {
- LOG_ALWAYS_FATAL_IF(*(op.layerHandle) != nullptr, "layer already exists!");
- *(op.layerHandle) = renderer.copyToLayer(state.computedState.clippedBounds);
- LOG_ALWAYS_FATAL_IF(*op.layerHandle == nullptr, "layer copy failed");
-}
-
-void BakedOpDispatcher::onCopyFromLayerOp(BakedOpRenderer& renderer, const CopyFromLayerOp& op,
- const BakedOpState& state) {
- LOG_ALWAYS_FATAL_IF(*op.layerHandle == nullptr, "no layer to draw underneath!");
- if (!state.computedState.clippedBounds.isEmpty()) {
- if (op.paint && op.paint->getAlpha() < 255) {
- SkPaint layerPaint;
- layerPaint.setAlpha(op.paint->getAlpha());
- layerPaint.setBlendMode(SkBlendMode::kDstIn);
- layerPaint.setColorFilter(sk_ref_sp(op.paint->getColorFilter()));
- RectOp rectOp(state.computedState.clippedBounds, Matrix4::identity(), nullptr,
- &layerPaint);
- BakedOpDispatcher::onRectOp(renderer, rectOp, state);
- }
-
- OffscreenBuffer& layer = **(op.layerHandle);
- auto mode = PaintUtils::getBlendModeDirect(op.paint);
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedUvQuad(nullptr, layer.getTextureCoordinates())
- .setFillLayer(layer.texture, nullptr, 1.0f, mode, Blend::ModeOrderSwap::Swap)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRect(state.computedState.clippedBounds)
- .build();
- renderer.renderGlop(state, glop);
- }
- renderer.renderState().layerPool().putOrDelete(*op.layerHandle);
-}
-
-} // namespace uirenderer
-} // namespace android
diff --git a/libs/hwui/BakedOpDispatcher.h b/libs/hwui/BakedOpDispatcher.h
deleted file mode 100644
index cc32870..0000000
--- a/libs/hwui/BakedOpDispatcher.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef ANDROID_HWUI_BAKED_OP_DISPATCHER_H
-#define ANDROID_HWUI_BAKED_OP_DISPATCHER_H
-
-#include "BakedOpState.h"
-#include "RecordedOp.h"
-
-namespace android {
-namespace uirenderer {
-
-class BakedOpRenderer;
-
-/**
- * Provides all "onBitmapOp(...)" style static methods for every op type, which convert the
- * RecordedOps and their state to Glops, and renders them with the provided BakedOpRenderer.
- *
- * onXXXOp methods must either render directly with the renderer, or call a static renderYYY
- * method to render content. There should never be draw content rejection in BakedOpDispatcher -
- * it must happen at a higher level (except in error-ish cases, like texture-too-big).
- */
-class BakedOpDispatcher {
-public:
-// Declares all "onMergedBitmapOps(...)" style methods for mergeable op types
-#define X(Type) \
- static void onMerged##Type##s(BakedOpRenderer& renderer, const MergedBakedOpList& opList);
- MAP_MERGEABLE_OPS(X)
-#undef X
-
-// Declares all "onBitmapOp(...)" style methods for every op type
-#define X(Type) \
- static void on##Type(BakedOpRenderer& renderer, const Type& op, const BakedOpState& state);
- MAP_RENDERABLE_OPS(X)
-#undef X
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_BAKED_OP_DISPATCHER_H
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
deleted file mode 100644
index 0a3e3e4..0000000
--- a/libs/hwui/BakedOpRenderer.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2015 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 "BakedOpRenderer.h"
-
-#include "Caches.h"
-#include "Glop.h"
-#include "GlopBuilder.h"
-#include "VertexBuffer.h"
-#include "renderstate/OffscreenBufferPool.h"
-#include "renderstate/RenderState.h"
-#include "utils/GLUtils.h"
-
-#include <algorithm>
-
-namespace android {
-namespace uirenderer {
-
-OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) {
- LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
-
- OffscreenBuffer* buffer =
- mRenderState.layerPool().get(mRenderState, width, height, mWideColorGamut);
- startRepaintLayer(buffer, Rect(width, height));
- return buffer;
-}
-
-void BakedOpRenderer::recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) {
- mRenderState.layerPool().putOrDelete(offscreenBuffer);
-}
-
-void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
- LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
-
- // subtract repaintRect from region, since it will be regenerated
- if (repaintRect.contains(0, 0, offscreenBuffer->viewportWidth,
- offscreenBuffer->viewportHeight)) {
- // repaint full layer, so throw away entire region
- offscreenBuffer->region.clear();
- } else {
- offscreenBuffer->region.subtractSelf(android::Rect(repaintRect.left, repaintRect.top,
- repaintRect.right, repaintRect.bottom));
- }
-
- mRenderTarget.offscreenBuffer = offscreenBuffer;
- mRenderTarget.offscreenBuffer->hasRenderedSinceRepaint = false;
-
- // create and bind framebuffer
- mRenderTarget.frameBufferId = mRenderState.createFramebuffer();
- mRenderState.bindFramebuffer(mRenderTarget.frameBufferId);
-
- // attach the texture to the FBO
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- offscreenBuffer->texture.id(), 0);
- GL_CHECKPOINT(LOW);
-
- int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- LOG_ALWAYS_FATAL_IF(status != GL_FRAMEBUFFER_COMPLETE,
- "framebuffer incomplete, status %d, textureId %d, size %dx%d", status,
- offscreenBuffer->texture.id(), offscreenBuffer->texture.width(),
- offscreenBuffer->texture.height());
-
- // Change the viewport & ortho projection
- setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight);
-
- clearColorBuffer(repaintRect);
-}
-
-void BakedOpRenderer::endLayer() {
- if (mRenderTarget.stencil) {
- // if stencil was used for clipping, detach it and return it to pool
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
- GL_CHECKPOINT(MODERATE);
- mRenderTarget.stencil = nullptr;
- }
- mRenderTarget.lastStencilClip = nullptr;
-
- mRenderTarget.offscreenBuffer->updateMeshFromRegion();
- mRenderTarget.offscreenBuffer = nullptr; // It's in drawLayerOp's hands now.
-
- // Detach the texture from the FBO
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- GL_CHECKPOINT(LOW);
- mRenderState.deleteFramebuffer(mRenderTarget.frameBufferId);
- mRenderTarget.frameBufferId = 0;
-}
-
-OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
- const uint32_t width = area.getWidth();
- const uint32_t height = area.getHeight();
- OffscreenBuffer* buffer =
- mRenderState.layerPool().get(mRenderState, width, height, mWideColorGamut);
- if (!area.isEmpty() && width != 0 && height != 0) {
- mCaches.textureState().activateTexture(0);
- mCaches.textureState().bindTexture(buffer->texture.id());
-
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, area.left,
- mRenderTarget.viewportHeight - area.bottom, width, height);
- }
- return buffer;
-}
-
-void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {
- LOG_ALWAYS_FATAL_IF(mRenderTarget.frameBufferId != 0, "primary framebufferId must be 0");
- mRenderState.bindFramebuffer(0);
- setViewport(width, height);
-
- if (!mOpaque) {
- clearColorBuffer(repaintRect);
- }
-
- mRenderState.debugOverdraw(true, true);
-}
-
-void BakedOpRenderer::endFrame(const Rect& repaintRect) {
- if (CC_UNLIKELY(Properties::debugOverdraw)) {
- ClipRect overdrawClip(repaintRect);
- Rect viewportRect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight);
- // overdraw visualization
- for (int i = 1; i <= 4; i++) {
- if (i < 4) {
- // nth level of overdraw tests for n+1 draws per pixel
- mRenderState.stencil().enableDebugTest(i + 1, false);
- } else {
- // 4th level tests for 4 or higher draws per pixel
- mRenderState.stencil().enableDebugTest(4, true);
- }
-
- SkPaint paint;
- paint.setColor(mCaches.getOverdrawColor(i));
- Glop glop;
- GlopBuilder(mRenderState, mCaches, &glop)
- .setRoundRectClipState(nullptr)
- .setMeshUnitQuad()
- .setFillPaint(paint, 1.0f)
- .setTransform(Matrix4::identity(), TransformFlags::None)
- .setModelViewMapUnitToRect(viewportRect)
- .build();
- renderGlop(nullptr, &overdrawClip, glop);
- }
- mRenderState.stencil().disable();
- }
-
- // Note: we leave FBO 0 renderable here, for post-frame-content decoration
-}
-
-void BakedOpRenderer::setViewport(uint32_t width, uint32_t height) {
- mRenderTarget.viewportWidth = width;
- mRenderTarget.viewportHeight = height;
- mRenderTarget.orthoMatrix.loadOrtho(width, height);
-
- mRenderState.setViewport(width, height);
- mRenderState.blend().syncEnabled();
-}
-
-void BakedOpRenderer::clearColorBuffer(const Rect& rect) {
- if (rect.contains(Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight))) {
- // Full viewport is being cleared - disable scissor
- mRenderState.scissor().setEnabled(false);
- } else {
- // Requested rect is subset of viewport - scissor to it to avoid over-clearing
- mRenderState.scissor().setEnabled(true);
- mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom,
- rect.getWidth(), rect.getHeight());
- }
- glClear(GL_COLOR_BUFFER_BIT);
- if (!mRenderTarget.frameBufferId) mHasDrawn = true;
-}
-
-Texture* BakedOpRenderer::getTexture(Bitmap* bitmap) {
- return nullptr;
-}
-
-void BakedOpRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
- std::vector<Vertex> vertices;
- vertices.reserve(count);
- Vertex* vertex = vertices.data();
-
- for (int index = 0; index < count; index += 4) {
- float l = rects[index + 0];
- float t = rects[index + 1];
- float r = rects[index + 2];
- float b = rects[index + 3];
-
- Vertex::set(vertex++, l, t);
- Vertex::set(vertex++, r, t);
- Vertex::set(vertex++, l, b);
- Vertex::set(vertex++, r, b);
- }
-
- LOG_ALWAYS_FATAL_IF(mRenderTarget.frameBufferId != 0, "decoration only supported for FBO 0");
- // TODO: Currently assume full FBO damage, due to FrameInfoVisualizer::unionDirty.
- // Should should scissor/set mHasDrawn safely.
- mRenderState.scissor().setEnabled(false);
- Glop glop;
- GlopBuilder(mRenderState, mCaches, &glop)
- .setRoundRectClipState(nullptr)
- .setMeshIndexedQuads(vertices.data(), count / 4)
- .setFillPaint(*paint, 1.0f)
- .setTransform(Matrix4::identity(), TransformFlags::None)
- .setModelViewIdentityEmptyBounds()
- .build();
- mRenderState.render(glop, mRenderTarget.orthoMatrix, false);
- mHasDrawn = true;
-}
-
-// clears and re-fills stencil with provided rendertarget space quads,
-// and then put stencil into test mode
-void BakedOpRenderer::setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold) {
- mRenderState.stencil().enableWrite(incrementThreshold);
- mRenderState.stencil().clear();
- Glop glop;
- GlopBuilder(mRenderState, mCaches, &glop)
- .setRoundRectClipState(nullptr)
- .setMeshIndexedQuads(quadVertices.data(), quadVertices.size() / 4)
- .setFillBlack()
- .setTransform(Matrix4::identity(), TransformFlags::None)
- .setModelViewIdentityEmptyBounds()
- .build();
- mRenderState.render(glop, mRenderTarget.orthoMatrix, false);
- mRenderState.stencil().enableTest(incrementThreshold);
-}
-
-void BakedOpRenderer::setupStencilRectList(const ClipBase* clip) {
- LOG_ALWAYS_FATAL_IF(clip->mode != ClipMode::RectangleList,
- "can't rectlist clip without rectlist");
- auto&& rectList = reinterpret_cast<const ClipRectList*>(clip)->rectList;
- int quadCount = rectList.getTransformedRectanglesCount();
- std::vector<Vertex> rectangleVertices;
- rectangleVertices.reserve(quadCount * 4);
- for (int i = 0; i < quadCount; i++) {
- const TransformedRectangle& tr(rectList.getTransformedRectangle(i));
- const Matrix4& transform = tr.getTransform();
- Rect bounds = tr.getBounds();
- if (transform.rectToRect()) {
- // If rectToRect, can simply map bounds before storing verts
- transform.mapRect(bounds);
- bounds.doIntersect(clip->rect);
- if (bounds.isEmpty()) {
- continue; // will be outside of scissor, skip
- }
- }
-
- rectangleVertices.push_back(Vertex{bounds.left, bounds.top});
- rectangleVertices.push_back(Vertex{bounds.right, bounds.top});
- rectangleVertices.push_back(Vertex{bounds.left, bounds.bottom});
- rectangleVertices.push_back(Vertex{bounds.right, bounds.bottom});
-
- if (!transform.rectToRect()) {
- // If not rectToRect, must map each point individually
- for (auto cur = rectangleVertices.end() - 4; cur < rectangleVertices.end(); cur++) {
- transform.mapPoint(cur->x, cur->y);
- }
- }
- }
- setupStencilQuads(rectangleVertices, rectList.getTransformedRectanglesCount());
-}
-
-void BakedOpRenderer::setupStencilRegion(const ClipBase* clip) {
- LOG_ALWAYS_FATAL_IF(clip->mode != ClipMode::Region, "can't region clip without region");
- auto&& region = reinterpret_cast<const ClipRegion*>(clip)->region;
-
- std::vector<Vertex> regionVertices;
- SkRegion::Cliperator it(region, clip->rect.toSkIRect());
- while (!it.done()) {
- const SkIRect& r = it.rect();
- regionVertices.push_back(Vertex{(float)r.fLeft, (float)r.fTop});
- regionVertices.push_back(Vertex{(float)r.fRight, (float)r.fTop});
- regionVertices.push_back(Vertex{(float)r.fLeft, (float)r.fBottom});
- regionVertices.push_back(Vertex{(float)r.fRight, (float)r.fBottom});
- it.next();
- }
- setupStencilQuads(regionVertices, 0);
-}
-
-void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const ClipBase* clip) {
- // Prepare scissor (done before stencil, to simplify filling stencil)
- mRenderState.scissor().setEnabled(clip != nullptr);
- if (clip) {
- mRenderState.scissor().set(mRenderTarget.viewportHeight, clip->rect);
- }
-
- // If stencil may be used for clipping, enable it, fill it, or disable it as appropriate
- if (CC_LIKELY(!Properties::debugOverdraw)) {
- // only modify stencil mode and content when it's not used for overdraw visualization
- if (CC_UNLIKELY(clip && clip->mode != ClipMode::Rectangle)) {
- // NOTE: this pointer check is only safe for non-rect clips,
- // since rect clips may be created on the stack
- if (mRenderTarget.lastStencilClip != clip) {
- // Stencil needed, but current stencil isn't up to date
- mRenderTarget.lastStencilClip = clip;
-
- // DEAD CODE
-
- if (clip->mode == ClipMode::RectangleList) {
- setupStencilRectList(clip);
- } else {
- setupStencilRegion(clip);
- }
- } else {
- // stencil is up to date - just need to ensure it's enabled (since an unclipped
- // or scissor-only clipped op may have been drawn, disabling the stencil)
- int incrementThreshold = 0;
- if (CC_LIKELY(clip->mode == ClipMode::RectangleList)) {
- auto&& rectList = reinterpret_cast<const ClipRectList*>(clip)->rectList;
- incrementThreshold = rectList.getTransformedRectanglesCount();
- }
- mRenderState.stencil().enableTest(incrementThreshold);
- }
- } else {
- // either scissor or no clip, so disable stencil test
- mRenderState.stencil().disable();
- }
- }
-
- if (dirtyBounds) {
- // dirty offscreenbuffer if present
- dirtyRenderTarget(*dirtyBounds);
- }
-}
-
-void BakedOpRenderer::renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip,
- const Glop& glop) {
- prepareRender(dirtyBounds, clip);
- // Disable blending if this is the first draw to the main framebuffer, in case app has defined
- // transparency where it doesn't make sense - as first draw in opaque window. Note that we only
- // apply this improvement when the blend mode is SRC_OVER - other modes (e.g. CLEAR) can be
- // valid draws that affect other content (e.g. draw CLEAR, then draw DST_OVER)
- bool overrideDisableBlending = !mHasDrawn && mOpaque && !mRenderTarget.frameBufferId &&
- glop.blend.src == GL_ONE &&
- glop.blend.dst == GL_ONE_MINUS_SRC_ALPHA;
- mRenderState.render(glop, mRenderTarget.orthoMatrix, overrideDisableBlending);
- if (!mRenderTarget.frameBufferId) mHasDrawn = true;
-}
-
-void BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& state) {
- prepareRender(&state.computedState.clippedBounds, state.computedState.getClipIfNeeded());
-
- DrawGlInfo info;
- auto&& clip = state.computedState.clipRect();
- info.clipLeft = clip.left;
- info.clipTop = clip.top;
- info.clipRight = clip.right;
- info.clipBottom = clip.bottom;
- info.isLayer = offscreenRenderTarget();
- info.width = mRenderTarget.viewportWidth;
- info.height = mRenderTarget.viewportHeight;
- state.computedState.transform.copyTo(&info.transform[0]);
-
- mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info);
- if (!mRenderTarget.frameBufferId) mHasDrawn = true;
-}
-
-void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
- if (mRenderTarget.offscreenBuffer) {
- mRenderTarget.offscreenBuffer->dirty(uiDirty);
- }
-}
-
-} // namespace uirenderer
-} // namespace android
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
deleted file mode 100644
index 72c9365..0000000
--- a/libs/hwui/BakedOpRenderer.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2015 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 "BakedOpState.h"
-#include "Lighting.h"
-#include "Matrix.h"
-#include "utils/Macros.h"
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-struct Glop;
-class Layer;
-struct RenderBuffer;
-class RenderState;
-struct ClipBase;
-
-/**
- * Main rendering manager for a collection of work - one frame + any contained FBOs.
- *
- * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only
- * place where FBOs are bound, created, and destroyed.
- *
- * All rendering operations will be sent by the Dispatcher, a collection of static methods,
- * which has intentionally limited access to the renderer functionality.
- */
-class BakedOpRenderer {
-public:
- typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&);
-
- BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
- const LightInfo& lightInfo)
- : mGlopReceiver(DefaultGlopReceiver)
- , mRenderState(renderState)
- , mCaches(caches)
- , mOpaque(opaque)
- , mWideColorGamut(wideColorGamut)
- , mLightInfo(lightInfo) {}
-
- RenderState& renderState() { return mRenderState; }
- Caches& caches() { return mCaches; }
-
- void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
- void endFrame(const Rect& repaintRect);
- WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
- void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer);
- void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
- void endLayer();
- WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);
-
- Texture* getTexture(Bitmap* bitmap);
- const LightInfo& getLightInfo() const { return mLightInfo; }
-
- void renderGlop(const BakedOpState& state, const Glop& glop) {
- renderGlop(&state.computedState.clippedBounds, state.computedState.getClipIfNeeded(), glop);
- }
- void renderFunctor(const FunctorOp& op, const BakedOpState& state);
-
- void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) {
- mGlopReceiver(*this, dirtyBounds, clip, glop);
- }
- bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
- void dirtyRenderTarget(const Rect& dirtyRect);
- bool didDraw() const { return mHasDrawn; }
-
- uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; }
- uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; }
-
- // simple draw methods, to be used for end frame decoration
- void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) {
- float ltrb[4] = {left, top, right, bottom};
- drawRects(ltrb, 4, paint);
- }
- void drawRects(const float* rects, int count, const SkPaint* paint);
-
-protected:
- GlopReceiver mGlopReceiver;
-
-private:
- static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
- const ClipBase* clip, const Glop& glop) {
- renderer.renderGlopImpl(dirtyBounds, clip, glop);
- }
- void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop);
- void setViewport(uint32_t width, uint32_t height);
- void clearColorBuffer(const Rect& clearRect);
- void prepareRender(const Rect* dirtyBounds, const ClipBase* clip);
- void setupStencilRectList(const ClipBase* clip);
- void setupStencilRegion(const ClipBase* clip);
- void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold);
-
- RenderState& mRenderState;
- Caches& mCaches;
- bool mOpaque;
- bool mWideColorGamut;
- bool mHasDrawn = false;
-
- // render target state - setup by start/end layer/frame
- // only valid to use in between start/end pairs.
- struct {
- // If not drawing to a layer: fbo = 0, offscreenBuffer = null,
- // Otherwise these refer to currently painting layer's state
- GLuint frameBufferId = 0;
- OffscreenBuffer* offscreenBuffer = nullptr;
-
- // Used when drawing to a layer and using stencil clipping. otherwise null.
- RenderBuffer* stencil = nullptr;
-
- // value representing the ClipRectList* or ClipRegion* currently stored in
- // the stencil of the current render target
- const ClipBase* lastStencilClip = nullptr;
-
- // Size of renderable region in current render target - for layers, may not match actual
- // bounds of FBO texture. offscreenBuffer->texture has this information.
- uint32_t viewportWidth = 0;
- uint32_t viewportHeight = 0;
-
- Matrix4 orthoMatrix;
- } mRenderTarget;
-
- const LightInfo mLightInfo;
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
deleted file mode 100644
index 0c673f3..0000000
--- a/libs/hwui/BakedOpState.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2015 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 "BakedOpState.h"
-
-#include "ClipArea.h"
-
-namespace android {
-namespace uirenderer {
-
-static int computeClipSideFlags(const Rect& clip, const Rect& bounds) {
- int clipSideFlags = 0;
- if (clip.left > bounds.left) clipSideFlags |= OpClipSideFlags::Left;
- if (clip.top > bounds.top) clipSideFlags |= OpClipSideFlags::Top;
- if (clip.right < bounds.right) clipSideFlags |= OpClipSideFlags::Right;
- if (clip.bottom < bounds.bottom) clipSideFlags |= OpClipSideFlags::Bottom;
- return clipSideFlags;
-}
-
-ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp, bool expandForStroke,
- bool expandForPathTexture) {
- // resolvedMatrix = parentMatrix * localMatrix
- transform.loadMultiply(*snapshot.transform, recordedOp.localMatrix);
-
- // resolvedClippedBounds = intersect(resolvedMatrix * opBounds, resolvedClipRect)
- clippedBounds = recordedOp.unmappedBounds;
- if (CC_UNLIKELY(expandForStroke)) {
- // account for non-hairline stroke
- clippedBounds.outset(recordedOp.paint->getStrokeWidth() * 0.5f);
- } else if (CC_UNLIKELY(expandForPathTexture)) {
- clippedBounds.outset(1);
- }
- transform.mapRect(clippedBounds);
- if (CC_UNLIKELY(expandForStroke &&
- (!transform.isPureTranslate() || recordedOp.paint->getStrokeWidth() < 1.0f))) {
- // account for hairline stroke when stroke may be < 1 scaled pixel
- // Non translate || strokeWidth < 1 is conservative, but will cover all cases
- clippedBounds.outset(0.5f);
- }
-
- // resolvedClipRect = intersect(parentMatrix * localClip, parentClip)
- clipState = snapshot.serializeIntersectedClip(allocator, recordedOp.localClip,
- *(snapshot.transform));
- LOG_ALWAYS_FATAL_IF(!clipState, "must clip!");
-
- const Rect& clipRect = clipState->rect;
- if (CC_UNLIKELY(clipRect.isEmpty() || !clippedBounds.intersects(clipRect))) {
- // Rejected based on either empty clip, or bounds not intersecting with clip
-
- // Note: we could rewind the clipState object in situations where the clipRect is empty,
- // but *only* if the caching logic within ClipArea was aware of the rewind.
- clipState = nullptr;
- clippedBounds.setEmpty();
- } else {
- // Not rejected! compute true clippedBounds, clipSideFlags, and path mask
- clipSideFlags = computeClipSideFlags(clipRect, clippedBounds);
- clippedBounds.doIntersect(clipRect);
-
- if (CC_UNLIKELY(snapshot.projectionPathMask)) {
- // map projection path mask from render target space into op space,
- // so intersection with op geometry is possible
- Matrix4 inverseTransform;
- inverseTransform.loadInverse(transform);
- SkMatrix skInverseTransform;
- inverseTransform.copyTo(skInverseTransform);
-
- auto localMask = allocator.create<SkPath>();
- snapshot.projectionPathMask->transform(skInverseTransform, localMask);
- localProjectionPathMask = localMask;
- }
- }
-}
-
-ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
- const Matrix4& localTransform, const ClipBase* localClip) {
- transform.loadMultiply(*snapshot.transform, localTransform);
- clipState = snapshot.serializeIntersectedClip(allocator, localClip, *(snapshot.transform));
- clippedBounds = clipState->rect;
- clipSideFlags = OpClipSideFlags::Full;
- localProjectionPathMask = nullptr;
-}
-
-ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot)
- : transform(*snapshot.transform)
- , clipState(snapshot.mutateClipArea().serializeClip(allocator))
- , clippedBounds(clipState->rect)
- , clipSideFlags(OpClipSideFlags::Full)
- , localProjectionPathMask(nullptr) {}
-
-ResolvedRenderState::ResolvedRenderState(const ClipRect* clipRect, const Rect& dstRect)
- : transform(Matrix4::identity())
- , clipState(clipRect)
- , clippedBounds(dstRect)
- , clipSideFlags(computeClipSideFlags(clipRect->rect, dstRect))
- , localProjectionPathMask(nullptr) {
- clippedBounds.doIntersect(clipRect->rect);
-}
-
-BakedOpState* BakedOpState::tryConstruct(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp) {
- if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
- BakedOpState* bakedState =
- allocator.create_trivial<BakedOpState>(allocator, snapshot, recordedOp, false, false);
- if (bakedState->computedState.clippedBounds.isEmpty()) {
- // bounds are empty, so op is rejected
- allocator.rewindIfLastAlloc(bakedState);
- return nullptr;
- }
- return bakedState;
-}
-
-BakedOpState* BakedOpState::tryConstructUnbounded(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp) {
- if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
- return allocator.create_trivial<BakedOpState>(allocator, snapshot, recordedOp);
-}
-
-BakedOpState* BakedOpState::tryStrokeableOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp,
- StrokeBehavior strokeBehavior,
- bool expandForPathTexture) {
- if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
- bool expandForStroke =
- (strokeBehavior == StrokeBehavior::Forced ||
- (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style));
-
- BakedOpState* bakedState = allocator.create_trivial<BakedOpState>(
- allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture);
- if (bakedState->computedState.clippedBounds.isEmpty()) {
- // bounds are empty, so op is rejected
- // NOTE: this won't succeed if a clip was allocated
- allocator.rewindIfLastAlloc(bakedState);
- return nullptr;
- }
- return bakedState;
-}
-
-BakedOpState* BakedOpState::directConstruct(LinearAllocator& allocator, const ClipRect* clip,
- const Rect& dstRect, const RecordedOp& recordedOp) {
- return allocator.create_trivial<BakedOpState>(clip, dstRect, recordedOp);
-}
-
-void BakedOpState::setupOpacity(const SkPaint* paint) {
- computedState.opaqueOverClippedBounds = computedState.transform.isSimple() &&
- computedState.clipState->mode == ClipMode::Rectangle &&
- MathUtils::areEqual(alpha, 1.0f) &&
- !roundRectClipState && PaintUtils::isOpaquePaint(paint);
-}
-
-} // namespace uirenderer
-} // namespace android
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
deleted file mode 100644
index a50feff..0000000
--- a/libs/hwui/BakedOpState.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef ANDROID_HWUI_BAKED_OP_STATE_H
-#define ANDROID_HWUI_BAKED_OP_STATE_H
-
-#include "Matrix.h"
-#include "RecordedOp.h"
-#include "Rect.h"
-#include "Snapshot.h"
-
-namespace android {
-namespace uirenderer {
-
-class BakedOpState;
-
-namespace OpClipSideFlags {
-enum {
- None = 0x0,
- Left = 0x1,
- Top = 0x2,
- Right = 0x4,
- Bottom = 0x8,
- Full = 0xF,
- // ConservativeFull = 0x1F needed?
-};
-}
-
-/**
- * Holds a list of BakedOpStates of ops that can be drawn together
- */
-struct MergedBakedOpList {
- const BakedOpState* const* states;
- size_t count;
- int clipSideFlags;
- Rect clip;
-};
-
-/**
- * Holds the resolved clip, transform, and bounds of a recordedOp, when replayed with a snapshot
- */
-class ResolvedRenderState {
-public:
- ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp, bool expandForStroke,
- bool expandForPathTexture);
-
- // Constructor for unbounded ops *with* transform/clip
- ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
- const Matrix4& localTransform, const ClipBase* localClip);
-
- // Constructor for unbounded ops without transform/clip (namely shadows)
- ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);
-
- // Constructor for primitive ops provided clip, and no transform
- ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);
-
- Rect computeLocalSpaceClip() const {
- Matrix4 inverse;
- inverse.loadInverse(transform);
-
- Rect outClip(clipRect());
- inverse.mapRect(outClip);
- return outClip;
- }
-
- const Rect& clipRect() const { return clipState->rect; }
-
- bool requiresClip() const {
- return clipSideFlags != OpClipSideFlags::None ||
- CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
- }
-
- // returns the clip if it's needed to draw the operation, otherwise nullptr
- const ClipBase* getClipIfNeeded() const { return requiresClip() ? clipState : nullptr; }
-
- Matrix4 transform;
- const ClipBase* clipState = nullptr;
- Rect clippedBounds;
- int clipSideFlags = 0;
- const SkPath* localProjectionPathMask = nullptr;
- bool opaqueOverClippedBounds = false;
-};
-
-/**
- * Self-contained op wrapper, containing all resolved state required to draw the op.
- *
- * Stashed pointers within all point to longer lived objects, with no ownership implied.
- */
-class BakedOpState {
-public:
- static BakedOpState* tryConstruct(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp);
-
- static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp);
-
- enum class StrokeBehavior {
- // stroking is forced, regardless of style on paint (such as for lines)
- Forced,
- // stroking is defined by style on paint
- StyleDefined,
- };
-
- static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
- const RecordedOp& recordedOp,
- StrokeBehavior strokeBehavior,
- bool expandForPathTexture);
-
- static BakedOpState* directConstruct(LinearAllocator& allocator, const ClipRect* clip,
- const Rect& dstRect, const RecordedOp& recordedOp);
-
- // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent.
- void setupOpacity(const SkPaint* paint);
-
- // computed state:
- ResolvedRenderState computedState;
-
- // simple state (straight pointer/value storage):
- const float alpha;
- const RoundRectClipState* roundRectClipState;
- const RecordedOp* op;
-
-private:
- friend class LinearAllocator;
-
- BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp,
- bool expandForStroke, bool expandForPathTexture)
- : computedState(allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture)
- , alpha(snapshot.alpha)
- , roundRectClipState(snapshot.roundRectClipState)
- , op(&recordedOp) {}
-
- // TODO: fix this brittleness
- BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
- : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
- , alpha(snapshot.alpha)
- , roundRectClipState(snapshot.roundRectClipState)
- , op(&recordedOp) {}
-
- BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
- : computedState(clipRect, dstRect)
- , alpha(1.0f)
- , roundRectClipState(nullptr)
- , op(&recordedOp) {}
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_BAKED_OP_STATE_H
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 74e0997..891de5e 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -188,12 +188,7 @@
///////////////////////////////////////////////////////////////////////////////
TextureVertex* Caches::getRegionMesh() {
- // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
- if (!mRegionMesh) {
- mRegionMesh.reset(new TextureVertex[kMaxNumberOfQuads * 4]);
- }
-
- return mRegionMesh.get();
+ return nullptr;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index 5aea04d..236a6b6 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -15,7 +15,6 @@
*/
#include "FrameInfoVisualizer.h"
-#include "BakedOpRenderer.h"
#include "IProfileRenderer.h"
#include "utils/Color.h"
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
deleted file mode 100644
index 13a4112..0000000
--- a/libs/hwui/GlopBuilder.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * Copyright (C) 2015 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 "GlopBuilder.h"
-
-#include "Caches.h"
-#include "GlLayer.h"
-#include "Glop.h"
-#include "Layer.h"
-#include "Matrix.h"
-#include "Patch.h"
-#include "SkiaShader.h"
-#include "Texture.h"
-#include "VertexBuffer.h"
-#include "renderstate/MeshState.h"
-#include "renderstate/RenderState.h"
-#include "utils/PaintUtils.h"
-
-#include <GLES2/gl2.h>
-#include <SkPaint.h>
-
-#define DEBUG_GLOP_BUILDER 0
-
-#if DEBUG_GLOP_BUILDER
-
-#define TRIGGER_STAGE(stageFlag) \
- LOG_ALWAYS_FATAL_IF((stageFlag)&mStageFlags, "Stage %d cannot be run twice", (stageFlag)); \
- mStageFlags = static_cast<StageFlags>(mStageFlags | (stageFlag))
-
-#define REQUIRE_STAGES(requiredFlags) \
- LOG_ALWAYS_FATAL_IF((mStageFlags & (requiredFlags)) != (requiredFlags), \
- "not prepared for current stage")
-
-#else
-
-#define TRIGGER_STAGE(stageFlag) ((void)0)
-#define REQUIRE_STAGES(requiredFlags) ((void)0)
-
-#endif
-
-namespace android {
-namespace uirenderer {
-
-static void setUnitQuadTextureCoords(Rect uvs, TextureVertex* quadVertex) {
- quadVertex[0] = {0, 0, uvs.left, uvs.top};
- quadVertex[1] = {1, 0, uvs.right, uvs.top};
- quadVertex[2] = {0, 1, uvs.left, uvs.bottom};
- quadVertex[3] = {1, 1, uvs.right, uvs.bottom};
-}
-
-GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop)
- : mRenderState(renderState), mCaches(caches), mShader(nullptr), mOutGlop(outGlop) {
- mStageFlags = kInitialStage;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Mesh
-////////////////////////////////////////////////////////////////////////////////
-
-GlopBuilder& GlopBuilder::setMeshTexturedIndexedVbo(GLuint vbo, GLsizei elementCount) {
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
- mOutGlop->mesh.indices = {mRenderState.meshState().getQuadListIBO(), nullptr};
- mOutGlop->mesh.vertices = {vbo, VertexAttribFlags::TextureCoord,
- nullptr, (const void*)kMeshTextureOffset,
- nullptr, kTextureVertexStride};
- mOutGlop->mesh.elementCount = elementCount;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshUnitQuad() {
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
- mOutGlop->mesh.indices = {0, nullptr};
- mOutGlop->mesh.vertices = {mRenderState.meshState().getUnitQuadVBO(),
- VertexAttribFlags::None,
- nullptr,
- nullptr,
- nullptr,
- kTextureVertexStride};
- mOutGlop->mesh.elementCount = 4;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) {
- if (uvMapper) {
- // can't use unit quad VBO, so build UV vertices manually
- return setMeshTexturedUvQuad(uvMapper, Rect(1, 1));
- }
-
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
- mOutGlop->mesh.indices = {0, nullptr};
- mOutGlop->mesh.vertices = {mRenderState.meshState().getUnitQuadVBO(),
- VertexAttribFlags::TextureCoord,
- nullptr,
- (const void*)kMeshTextureOffset,
- nullptr,
- kTextureVertexStride};
- mOutGlop->mesh.elementCount = 4;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect uvs) {
- TRIGGER_STAGE(kMeshStage);
-
- if (CC_UNLIKELY(uvMapper)) {
- uvMapper->map(uvs);
- }
- setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]);
-
- const TextureVertex* textureVertex = mOutGlop->mesh.mappedVertices;
- mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
- mOutGlop->mesh.indices = {0, nullptr};
- mOutGlop->mesh.vertices = {0,
- VertexAttribFlags::TextureCoord,
- &textureVertex[0].x,
- &textureVertex[0].u,
- nullptr,
- kTextureVertexStride};
- mOutGlop->mesh.elementCount = 4;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshIndexedQuads(Vertex* vertexData, int quadCount) {
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
- mOutGlop->mesh.indices = {mRenderState.meshState().getQuadListIBO(), nullptr};
- mOutGlop->mesh.vertices = {
- 0, VertexAttribFlags::None, vertexData, nullptr, nullptr, kVertexStride};
- mOutGlop->mesh.elementCount = 6 * quadCount;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount) {
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
- mOutGlop->mesh.indices = {mRenderState.meshState().getQuadListIBO(), nullptr};
- mOutGlop->mesh.vertices = {0,
- VertexAttribFlags::TextureCoord,
- &vertexData[0].x,
- &vertexData[0].u,
- nullptr,
- kTextureVertexStride};
- mOutGlop->mesh.elementCount = elementCount;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData,
- int elementCount) {
- TRIGGER_STAGE(kMeshStage);
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
- mOutGlop->mesh.indices = {0, nullptr};
- mOutGlop->mesh.vertices = {0,
- VertexAttribFlags::TextureCoord | VertexAttribFlags::Color,
- &vertexData[0].x,
- &vertexData[0].u,
- &vertexData[0].r,
- kColorTextureVertexStride};
- mOutGlop->mesh.elementCount = elementCount;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer) {
- TRIGGER_STAGE(kMeshStage);
-
- const VertexBuffer::MeshFeatureFlags flags = vertexBuffer.getMeshFeatureFlags();
-
- bool alphaVertex = flags & VertexBuffer::kAlpha;
- bool indices = flags & VertexBuffer::kIndices;
-
- mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
- mOutGlop->mesh.indices = {0, vertexBuffer.getIndices()};
- mOutGlop->mesh.vertices = {0,
- alphaVertex ? VertexAttribFlags::Alpha : VertexAttribFlags::None,
- vertexBuffer.getBuffer(),
- nullptr,
- nullptr,
- alphaVertex ? kAlphaVertexStride : kVertexStride};
- mOutGlop->mesh.elementCount =
- indices ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();
- mOutGlop->mesh.vertexCount = vertexBuffer.getVertexCount(); // used for glDrawRangeElements()
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setMeshPatchQuads(const Patch& patch) {
- // DEAD CODE
- return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Fill
-////////////////////////////////////////////////////////////////////////////////
-
-void GlopBuilder::setFill(int color, float alphaScale, SkBlendMode mode,
- Blend::ModeOrderSwap modeUsage, const SkShader* shader,
- const SkColorFilter* colorFilter) {
- if (mode != SkBlendMode::kClear) {
- if (!shader) {
- FloatColor c;
- c.set(color);
- c.r *= alphaScale;
- c.g *= alphaScale;
- c.b *= alphaScale;
- c.a *= alphaScale;
- mOutGlop->fill.color = c;
- } else {
- float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
- mOutGlop->fill.color = {1, 1, 1, alpha};
- }
- } else {
- mOutGlop->fill.color = {0, 0, 0, 1};
- }
-
- mOutGlop->blend = {GL_ZERO, GL_ZERO};
- if (mOutGlop->fill.color.a < 1.0f ||
- (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha) ||
- (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend) ||
- mOutGlop->roundRectClipState || PaintUtils::isBlendedShader(shader) ||
- PaintUtils::isBlendedColorFilter(colorFilter) || mode != SkBlendMode::kSrcOver) {
- if (CC_LIKELY(mode <= SkBlendMode::kScreen)) {
- Blend::getFactors(mode, modeUsage, &mOutGlop->blend.src, &mOutGlop->blend.dst);
- } else {
- // These blend modes are not supported by OpenGL directly and have
- // to be implemented using shaders. Since the shader will perform
- // the blending, don't enable GL blending off here
- // If the blend mode cannot be implemented using shaders, fall
- // back to the default SrcOver blend mode instead
- if (CC_UNLIKELY(mCaches.extensions().hasFramebufferFetch())) {
- mDescription.framebufferMode = mode;
- mDescription.swapSrcDst = (modeUsage == Blend::ModeOrderSwap::Swap);
- // blending in shader, don't enable
- } else {
- // unsupported
- Blend::getFactors(SkBlendMode::kSrcOver, modeUsage, &mOutGlop->blend.src,
- &mOutGlop->blend.dst);
- }
- }
- }
- mShader = shader; // shader resolved in ::build()
-
- if (colorFilter) {
- SkColor color;
- SkBlendMode bmode;
- SkScalar srcColorMatrix[20];
- if (colorFilter->asColorMode(&color, &bmode)) {
- mOutGlop->fill.filterMode = mDescription.colorOp =
- ProgramDescription::ColorFilterMode::Blend;
- mDescription.colorMode = bmode;
- mOutGlop->fill.filter.color.set(color);
- } else if (colorFilter->asColorMatrix(srcColorMatrix)) {
- mOutGlop->fill.filterMode = mDescription.colorOp =
- ProgramDescription::ColorFilterMode::Matrix;
-
- float* colorMatrix = mOutGlop->fill.filter.matrix.matrix;
- memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
- memcpy(&colorMatrix[4], &srcColorMatrix[5], 4 * sizeof(float));
- memcpy(&colorMatrix[8], &srcColorMatrix[10], 4 * sizeof(float));
- memcpy(&colorMatrix[12], &srcColorMatrix[15], 4 * sizeof(float));
-
- // Skia uses the range [0..255] for the addition vector, but we need
- // the [0..1] range to apply the vector in GLSL
- float* colorVector = mOutGlop->fill.filter.matrix.vector;
- colorVector[0] = EOCF(srcColorMatrix[4] / 255.0f);
- colorVector[1] = EOCF(srcColorMatrix[9] / 255.0f);
- colorVector[2] = EOCF(srcColorMatrix[14] / 255.0f);
- colorVector[3] = srcColorMatrix[19] / 255.0f; // alpha is linear
- } else {
- ALOGE("unsupported ColorFilter type: %s", colorFilter->getTypeName());
- LOG_ALWAYS_FATAL("unsupported ColorFilter");
- }
- } else {
- mOutGlop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
- }
-}
-
-GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, const int textureFillFlags,
- const SkPaint* paint, float alphaScale) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- GLenum filter = (textureFillFlags & TextureFillFlags::ForceFilter)
- ? GL_LINEAR
- : PaintUtils::getFilter(paint);
- mOutGlop->fill.texture = {&texture, filter, GL_CLAMP_TO_EDGE, nullptr};
-
- if (paint) {
- int color = paint->getColor();
- SkShader* shader = paint->getShader();
-
- if (!(textureFillFlags & TextureFillFlags::IsAlphaMaskTexture)) {
- // Texture defines color, so disable shaders, and reset all non-alpha color channels
- color |= 0x00FFFFFF;
- shader = nullptr;
- }
- setFill(color, alphaScale, paint->getBlendMode(), Blend::ModeOrderSwap::NoSwap, shader,
- paint->getColorFilter());
- } else {
- mOutGlop->fill.color = {alphaScale, alphaScale, alphaScale, alphaScale};
-
- if (alphaScale < 1.0f || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha) ||
- texture.blend || mOutGlop->roundRectClipState) {
- Blend::getFactors(SkBlendMode::kSrcOver, Blend::ModeOrderSwap::NoSwap,
- &mOutGlop->blend.src, &mOutGlop->blend.dst);
- } else {
- mOutGlop->blend = {GL_ZERO, GL_ZERO};
- }
- }
-
- if (textureFillFlags & TextureFillFlags::IsAlphaMaskTexture) {
- mDescription.modulate = mOutGlop->fill.color.isNotBlack();
- mDescription.hasAlpha8Texture = true;
- } else {
- mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
- }
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillPaint(const SkPaint& paint, float alphaScale, bool shadowInterp) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- if (CC_LIKELY(!shadowInterp)) {
- mOutGlop->fill.texture = {nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
- } else {
- mOutGlop->fill.texture = {mCaches.textureState().getShadowLutTexture(), GL_INVALID_ENUM,
- GL_INVALID_ENUM, nullptr};
- }
-
- setFill(paint.getColor(), alphaScale, paint.getBlendMode(), Blend::ModeOrderSwap::NoSwap,
- paint.getShader(), paint.getColorFilter());
- mDescription.useShadowAlphaInterp = shadowInterp;
- mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint,
- float alphaScale) {
- // DEAD CODE
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor,
- const SkPaint& paint, float alphaScale) {
- // DEAD CODE
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillBlack() {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- mOutGlop->fill.texture = {nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
- setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kSrcOver, Blend::ModeOrderSwap::NoSwap, nullptr,
- nullptr);
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillClear() {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- mOutGlop->fill.texture = {nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
- setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kClear, Blend::ModeOrderSwap::NoSwap, nullptr,
- nullptr);
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
- float alpha, SkBlendMode mode,
- Blend::ModeOrderSwap modeUsage) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- mOutGlop->fill.texture = {&texture, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr};
-
- setFill(SK_ColorWHITE, alpha, mode, modeUsage, nullptr, colorFilter);
-
- mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillTextureLayer(GlLayer& layer, float alpha) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- mOutGlop->fill.texture = {&(layer.getTexture()), GL_LINEAR, GL_CLAMP_TO_EDGE,
- &layer.getTexTransform()};
-
- setFill(SK_ColorWHITE, alpha, layer.getMode(), Blend::ModeOrderSwap::NoSwap, nullptr,
- layer.getColorFilter());
-
- mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
- mDescription.hasTextureTransform = true;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
- bool requiresFilter) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
- mOutGlop->fill.texture = {&texture, filter, GL_CLAMP_TO_EDGE, &textureTransform};
-
- setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr);
-
- mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
- mDescription.hasTextureTransform = true;
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setGammaCorrection(bool enabled) {
- REQUIRE_STAGES(kFillStage);
-
- mDescription.hasGammaCorrection = enabled;
- return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Transform
-////////////////////////////////////////////////////////////////////////////////
-
-GlopBuilder& GlopBuilder::setTransform(const Matrix4& canvas, const int transformFlags) {
- TRIGGER_STAGE(kTransformStage);
-
- mOutGlop->transform.canvas = canvas;
- mOutGlop->transform.transformFlags = transformFlags;
- return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ModelView
-////////////////////////////////////////////////////////////////////////////////
-
-GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) {
- TRIGGER_STAGE(kModelViewStage);
-
- mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f);
- mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setModelViewMapUnitToRectSnap(const Rect destination) {
- TRIGGER_STAGE(kModelViewStage);
- REQUIRE_STAGES(kTransformStage | kFillStage);
-
- float left = destination.left;
- float top = destination.top;
-
- const Matrix4& meshTransform = mOutGlop->transform.meshTransform();
- if (CC_LIKELY(meshTransform.isPureTranslate())) {
- // snap by adjusting the model view matrix
- const float translateX = meshTransform.getTranslateX();
- const float translateY = meshTransform.getTranslateY();
-
- left = (int)floorf(left + translateX + 0.5f) - translateX;
- top = (int)floorf(top + translateY + 0.5f) - translateY;
- mOutGlop->fill.texture.filter = GL_NEAREST;
- }
-
- mOutGlop->transform.modelView.loadTranslate(left, top, 0.0f);
- mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) {
- TRIGGER_STAGE(kModelViewStage);
-
- mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
- return *this;
-}
-
-GlopBuilder& GlopBuilder::setModelViewOffsetRectSnap(float offsetX, float offsetY,
- const Rect source) {
- TRIGGER_STAGE(kModelViewStage);
- REQUIRE_STAGES(kTransformStage | kFillStage);
-
- const Matrix4& meshTransform = mOutGlop->transform.meshTransform();
- if (CC_LIKELY(meshTransform.isPureTranslate())) {
- // snap by adjusting the model view matrix
- const float translateX = meshTransform.getTranslateX();
- const float translateY = meshTransform.getTranslateY();
-
- offsetX = (int)floorf(offsetX + translateX + source.left + 0.5f) - translateX - source.left;
- offsetY = (int)floorf(offsetY + translateY + source.top + 0.5f) - translateY - source.top;
- mOutGlop->fill.texture.filter = GL_NEAREST;
- }
-
- mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
- return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// RoundRectClip
-////////////////////////////////////////////////////////////////////////////////
-
-GlopBuilder& GlopBuilder::setRoundRectClipState(const RoundRectClipState* roundRectClipState) {
- TRIGGER_STAGE(kRoundRectClipStage);
-
- mOutGlop->roundRectClipState = roundRectClipState;
- mDescription.hasRoundRectClip = roundRectClipState != nullptr;
- return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Build
-////////////////////////////////////////////////////////////////////////////////
-
-void verify(const ProgramDescription& description, const Glop& glop) {
- if (glop.fill.texture.texture != nullptr) {
- LOG_ALWAYS_FATAL_IF(
- ((description.hasTexture && description.hasExternalTexture) ||
- (!description.hasTexture && !description.hasExternalTexture &&
- !description.useShadowAlphaInterp) ||
- ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) == 0 &&
- !description.useShadowAlphaInterp)),
- "Texture %p, hT%d, hET %d, attribFlags %x", glop.fill.texture.texture,
- description.hasTexture, description.hasExternalTexture,
- glop.mesh.vertices.attribFlags);
- } else {
- LOG_ALWAYS_FATAL_IF(
- (description.hasTexture || description.hasExternalTexture ||
- ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) != 0)),
- "No texture, hT%d, hET %d, attribFlags %x", description.hasTexture,
- description.hasExternalTexture, glop.mesh.vertices.attribFlags);
- }
-
- if ((glop.mesh.vertices.attribFlags & VertexAttribFlags::Alpha) &&
- glop.mesh.vertices.bufferObject) {
- LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible");
- }
-
- if (description.hasTextureTransform != (glop.fill.texture.textureTransform != nullptr)) {
- LOG_ALWAYS_FATAL("Texture transform incorrectly specified");
- }
-}
-
-void GlopBuilder::build() {
- REQUIRE_STAGES(kAllStages);
- if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) {
- Texture* texture = mOutGlop->fill.texture.texture;
- if (texture->target() == GL_TEXTURE_2D) {
- mDescription.hasTexture = true;
- } else {
- mDescription.hasExternalTexture = true;
- }
- mDescription.hasLinearTexture = texture->isLinear();
- mDescription.hasColorSpaceConversion = texture->hasColorSpaceConversion();
- mDescription.transferFunction = texture->getTransferFunctionType();
- mDescription.hasTranslucentConversion = texture->blend;
- }
-
- mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Color;
- mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha;
-
- // Enable debug highlight when what we're about to draw is tested against
- // the stencil buffer and if stencil highlight debugging is on
- mDescription.hasDebugHighlight =
- !Properties::debugOverdraw &&
- Properties::debugStencilClip == StencilClipDebug::ShowHighlight &&
- mRenderState.stencil().isTestEnabled();
-
- // serialize shader info into ShaderData
- GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;
-
- if (CC_LIKELY(!mShader)) {
- mOutGlop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType;
- } else {
- Matrix4 shaderMatrix;
- if (mOutGlop->transform.transformFlags & TransformFlags::MeshIgnoresCanvasTransform) {
- // canvas level transform was built into the modelView and geometry,
- // so the shader matrix must reverse this
- shaderMatrix.loadInverse(mOutGlop->transform.canvas);
- shaderMatrix.multiply(mOutGlop->transform.modelView);
- } else {
- shaderMatrix = mOutGlop->transform.modelView;
- }
- SkiaShader::store(mCaches, *mShader, shaderMatrix, &textureUnit, &mDescription,
- &(mOutGlop->fill.skiaShaderData));
- }
-
- // duplicates ProgramCache's definition of color uniform presence
- const bool singleColor = !mDescription.hasTexture && !mDescription.hasExternalTexture &&
- !mDescription.hasGradient && !mDescription.hasBitmap;
- mOutGlop->fill.colorEnabled = mDescription.modulate || singleColor;
-
- verify(mDescription, *mOutGlop);
-}
-
-void GlopBuilder::dump(const Glop& glop) {
- ALOGD("Glop Mesh");
- const Glop::Mesh& mesh = glop.mesh;
- ALOGD(" primitive mode: %d", mesh.primitiveMode);
- ALOGD(" indices: buffer obj %x, indices %p", mesh.indices.bufferObject,
- mesh.indices.indices);
-
- const Glop::Mesh::Vertices& vertices = glop.mesh.vertices;
- ALOGD(" vertices: buffer obj %x, flags %x, pos %p, tex %p, clr %p, stride %d",
- vertices.bufferObject, vertices.attribFlags, vertices.position, vertices.texCoord,
- vertices.color, vertices.stride);
- ALOGD(" element count: %d", mesh.elementCount);
-
- ALOGD("Glop Fill");
- const Glop::Fill& fill = glop.fill;
- ALOGD(" program %p", fill.program);
- if (fill.texture.texture) {
- ALOGD(" texture %p, target %d, filter %d, clamp %d", fill.texture.texture,
- fill.texture.texture->target(), fill.texture.filter, fill.texture.clamp);
- if (fill.texture.textureTransform) {
- fill.texture.textureTransform->dump("texture transform");
- }
- }
- ALOGD_IF(fill.colorEnabled, " color (argb) %.2f %.2f %.2f %.2f", fill.color.a, fill.color.r,
- fill.color.g, fill.color.b);
- ALOGD_IF(fill.filterMode != ProgramDescription::ColorFilterMode::None, " filterMode %d",
- (int)fill.filterMode);
- ALOGD_IF(fill.skiaShaderData.skiaShaderType, " shader type %d",
- fill.skiaShaderData.skiaShaderType);
-
- ALOGD("Glop transform");
- glop.transform.modelView.dump(" model view");
- glop.transform.canvas.dump(" canvas");
- ALOGD_IF(glop.transform.transformFlags, " transformFlags 0x%x", glop.transform.transformFlags);
-
- ALOGD_IF(glop.roundRectClipState, "Glop RRCS %p", glop.roundRectClipState);
-
- ALOGD("Glop blend %d %d", glop.blend.src, glop.blend.dst);
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
deleted file mode 100644
index dac3822..0000000
--- a/libs/hwui/GlopBuilder.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2015 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 "Glop.h"
-#include "Program.h"
-#include "renderstate/Blend.h"
-#include "utils/Macros.h"
-
-class SkPaint;
-class SkShader;
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-class GlLayer;
-class Matrix4;
-class Patch;
-class RenderState;
-class Texture;
-class UvMapper;
-class VertexBuffer;
-struct PathTexture;
-struct ShadowTexture;
-
-namespace TextureFillFlags {
-enum {
- None = 0,
- IsAlphaMaskTexture = 1 << 0,
- ForceFilter = 1 << 1,
-};
-}
-
-class GlopBuilder {
- PREVENT_COPY_AND_ASSIGN(GlopBuilder);
-
-public:
- GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop);
-
- GlopBuilder& setMeshTexturedIndexedVbo(GLuint vbo, GLsizei elementCount);
- GlopBuilder& setMeshUnitQuad();
- GlopBuilder& setMeshTexturedUnitQuad(const UvMapper* uvMapper);
- GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs);
- GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer);
- GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount);
- GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData,
- int elementCount); // TODO: use indexed quads
- GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData,
- int elementCount); // TODO: take quadCount
- GlopBuilder& setMeshPatchQuads(const Patch& patch);
-
- GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale,
- bool shadowInterp = false); // TODO: avoid boolean with default
- GlopBuilder& setFillTexturePaint(Texture& texture, const int textureFillFlags,
- const SkPaint* paint, float alphaScale);
- GlopBuilder& setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint,
- float alphaScale);
- GlopBuilder& setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor,
- const SkPaint& paint, float alphaScale);
- GlopBuilder& setFillBlack();
- GlopBuilder& setFillClear();
- GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter, float alpha,
- SkBlendMode mode, Blend::ModeOrderSwap modeUsage);
- 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,
- bool requiresFilter);
-
- GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
-
- GlopBuilder& setModelViewMapUnitToRect(const Rect destination);
- GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination);
- GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect& destination) {
- if (snap) {
- return setModelViewMapUnitToRectSnap(destination);
- } else {
- return setModelViewMapUnitToRect(destination);
- }
- }
- GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source);
- GlopBuilder& setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source);
- GlopBuilder& setModelViewOffsetRectOptionalSnap(bool snap, float offsetX, float offsetY,
- const Rect& source) {
- if (snap) {
- return setModelViewOffsetRectSnap(offsetX, offsetY, source);
- } else {
- return setModelViewOffsetRect(offsetX, offsetY, source);
- }
- }
- GlopBuilder& setModelViewIdentityEmptyBounds() {
- // pass empty rect since not needed for damage / snap
- return setModelViewOffsetRect(0, 0, Rect());
- }
-
- GlopBuilder& setRoundRectClipState(const RoundRectClipState* roundRectClipState);
-
- GlopBuilder& setGammaCorrection(bool enabled);
-
- void build();
-
- static void dump(const Glop& glop);
-
-private:
- void setFill(int color, float alphaScale, SkBlendMode mode, Blend::ModeOrderSwap modeUsage,
- const SkShader* shader, const SkColorFilter* colorFilter);
-
- enum StageFlags {
- kInitialStage = 0,
- kMeshStage = 1 << 0,
- kTransformStage = 1 << 1,
- kModelViewStage = 1 << 2,
- kFillStage = 1 << 3,
- kRoundRectClipStage = 1 << 4,
- kAllStages =
- kMeshStage | kFillStage | kTransformStage | kModelViewStage | kRoundRectClipStage,
- } mStageFlags;
-
- ProgramDescription mDescription;
- RenderState& mRenderState;
- Caches& mCaches;
- const SkShader* mShader;
- Glop* mOutGlop;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/LayerBuilder.cpp b/libs/hwui/LayerBuilder.cpp
deleted file mode 100644
index 15ede4c..0000000
--- a/libs/hwui/LayerBuilder.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "LayerBuilder.h"
-
-#include "BakedOpState.h"
-#include "RenderNode.h"
-#include "utils/PaintUtils.h"
-#include "utils/TraceUtils.h"
-
-#include <utils/TypeHelpers.h>
-
-namespace android {
-namespace uirenderer {
-
-class BatchBase {
-public:
- BatchBase(batchid_t batchId, BakedOpState* op, bool merging)
- : mBatchId(batchId), mMerging(merging) {
- mBounds = op->computedState.clippedBounds;
- mOps.push_back(op);
- }
-
- bool intersects(const Rect& rect) const {
- if (!rect.intersects(mBounds)) return false;
-
- for (const BakedOpState* op : mOps) {
- if (rect.intersects(op->computedState.clippedBounds)) {
- return true;
- }
- }
- return false;
- }
-
- batchid_t getBatchId() const { return mBatchId; }
- bool isMerging() const { return mMerging; }
-
- const std::vector<BakedOpState*>& getOps() const { return mOps; }
-
- void dump() const {
- ALOGD(" Batch %p, id %d, merging %d, count %d, bounds " RECT_STRING, this, mBatchId,
- mMerging, (int)mOps.size(), RECT_ARGS(mBounds));
- }
-
-protected:
- batchid_t mBatchId;
- Rect mBounds;
- std::vector<BakedOpState*> mOps;
- bool mMerging;
-};
-
-class OpBatch : public BatchBase {
-public:
- OpBatch(batchid_t batchId, BakedOpState* op) : BatchBase(batchId, op, false) {}
-
- void batchOp(BakedOpState* op) {
- mBounds.unionWith(op->computedState.clippedBounds);
- mOps.push_back(op);
- }
-};
-
-class MergingOpBatch : public BatchBase {
-public:
- MergingOpBatch(batchid_t batchId, BakedOpState* op)
- : BatchBase(batchId, op, true), mClipSideFlags(op->computedState.clipSideFlags) {}
-
- /*
- * Helper for determining if a new op can merge with a MergingDrawBatch based on their bounds
- * and clip side flags. Positive bounds delta means new bounds fit in old.
- */
- static inline bool checkSide(const int currentFlags, const int newFlags, const int side,
- float boundsDelta) {
- bool currentClipExists = currentFlags & side;
- bool newClipExists = newFlags & side;
-
- // if current is clipped, we must be able to fit new bounds in current
- if (boundsDelta > 0 && currentClipExists) return false;
-
- // if new is clipped, we must be able to fit current bounds in new
- if (boundsDelta < 0 && newClipExists) return false;
-
- return true;
- }
-
- static bool paintIsDefault(const SkPaint& paint) {
- return paint.getAlpha() == 255 && paint.getColorFilter() == nullptr &&
- paint.getShader() == nullptr;
- }
-
- static bool paintsAreEquivalent(const SkPaint& a, const SkPaint& b) {
- // Note: don't check color, since all currently mergeable ops can merge across colors
- return a.getAlpha() == b.getAlpha() && a.getColorFilter() == b.getColorFilter() &&
- a.getShader() == b.getShader();
- }
-
- /*
- * Checks if a (mergeable) op can be merged into this batch
- *
- * If true, the op's multiDraw must be guaranteed to handle both ops simultaneously, so it is
- * important to consider all paint attributes used in the draw calls in deciding both a) if an
- * op tries to merge at all, and b) if the op can merge with another set of ops
- *
- * False positives can lead to information from the paints of subsequent merged operations being
- * dropped, so we make simplifying qualifications on the ops that can merge, per op type.
- */
- bool canMergeWith(BakedOpState* op) const {
- bool isTextBatch =
- getBatchId() == OpBatchType::Text || getBatchId() == OpBatchType::ColorText;
-
- // Overlapping other operations is only allowed for text without shadow. For other ops,
- // multiDraw isn't guaranteed to overdraw correctly
- if (!isTextBatch || PaintUtils::hasTextShadow(op->op->paint)) {
- if (intersects(op->computedState.clippedBounds)) return false;
- }
-
- const BakedOpState* lhs = op;
- const BakedOpState* rhs = mOps[0];
-
- if (!MathUtils::areEqual(lhs->alpha, rhs->alpha)) return false;
-
- // Identical round rect clip state means both ops will clip in the same way, or not at all.
- // As the state objects are const, we can compare their pointers to determine mergeability
- if (lhs->roundRectClipState != rhs->roundRectClipState) return false;
-
- // Local masks prevent merge, since they're potentially in different coordinate spaces
- if (lhs->computedState.localProjectionPathMask ||
- rhs->computedState.localProjectionPathMask)
- return false;
-
- /* Clipping compatibility check
- *
- * Exploits the fact that if a op or batch is clipped on a side, its bounds will equal its
- * clip for that side.
- */
- const int currentFlags = mClipSideFlags;
- const int newFlags = op->computedState.clipSideFlags;
- if (currentFlags != OpClipSideFlags::None || newFlags != OpClipSideFlags::None) {
- const Rect& opBounds = op->computedState.clippedBounds;
- float boundsDelta = mBounds.left - opBounds.left;
- if (!checkSide(currentFlags, newFlags, OpClipSideFlags::Left, boundsDelta))
- return false;
- boundsDelta = mBounds.top - opBounds.top;
- if (!checkSide(currentFlags, newFlags, OpClipSideFlags::Top, boundsDelta)) return false;
-
- // right and bottom delta calculation reversed to account for direction
- boundsDelta = opBounds.right - mBounds.right;
- if (!checkSide(currentFlags, newFlags, OpClipSideFlags::Right, boundsDelta))
- return false;
- boundsDelta = opBounds.bottom - mBounds.bottom;
- if (!checkSide(currentFlags, newFlags, OpClipSideFlags::Bottom, boundsDelta))
- return false;
- }
-
- const SkPaint* newPaint = op->op->paint;
- const SkPaint* oldPaint = mOps[0]->op->paint;
-
- if (newPaint == oldPaint) {
- // if paints are equal, then modifiers + paint attribs don't need to be compared
- return true;
- } else if (newPaint && !oldPaint) {
- return paintIsDefault(*newPaint);
- } else if (!newPaint && oldPaint) {
- return paintIsDefault(*oldPaint);
- }
- return paintsAreEquivalent(*newPaint, *oldPaint);
- }
-
- void mergeOp(BakedOpState* op) {
- mBounds.unionWith(op->computedState.clippedBounds);
- mOps.push_back(op);
-
- // Because a new op must have passed canMergeWith(), we know it's passed the clipping compat
- // check, and doesn't extend past a side of the clip that's in use by the merged batch.
- // Therefore it's safe to simply always merge flags, and use the bounds as the clip rect.
- mClipSideFlags |= op->computedState.clipSideFlags;
- }
-
- int getClipSideFlags() const { return mClipSideFlags; }
- const Rect& getClipRect() const { return mBounds; }
-
-private:
- int mClipSideFlags;
-};
-
-LayerBuilder::LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect,
- const BeginLayerOp* beginLayerOp, RenderNode* renderNode)
- : width(width)
- , height(height)
- , repaintRect(repaintRect)
- , repaintClip(repaintRect)
- , offscreenBuffer(renderNode ? renderNode->getLayer() : nullptr)
- , beginLayerOp(beginLayerOp)
- , renderNode(renderNode) {}
-
-// iterate back toward target to see if anything drawn since should overlap the new op
-// if no target, merging ops still iterate to find similar batch to insert after
-void LayerBuilder::locateInsertIndex(int batchId, const Rect& clippedBounds,
- BatchBase** targetBatch, size_t* insertBatchIndex) const {
- for (int i = mBatches.size() - 1; i >= 0; i--) {
- BatchBase* overBatch = mBatches[i];
-
- if (overBatch == *targetBatch) break;
-
- // TODO: also consider shader shared between batch types
- if (batchId == overBatch->getBatchId()) {
- *insertBatchIndex = i + 1;
- if (!*targetBatch) break; // found insert position, quit
- }
-
- if (overBatch->intersects(clippedBounds)) {
- // NOTE: it may be possible to optimize for special cases where two operations
- // of the same batch/paint could swap order, such as with a non-mergeable
- // (clipped) and a mergeable text operation
- *targetBatch = nullptr;
- break;
- }
- }
-}
-
-void LayerBuilder::deferLayerClear(const Rect& rect) {
- mClearRects.push_back(rect);
-}
-
-void LayerBuilder::onDeferOp(LinearAllocator& allocator, const BakedOpState* bakedState) {
- if (bakedState->op->opId != RecordedOpId::CopyToLayerOp) {
- // First non-CopyToLayer, so stop stashing up layer clears for unclipped save layers,
- // and issue them together in one draw.
- flushLayerClears(allocator);
-
- if (CC_UNLIKELY(activeUnclippedSaveLayers.empty() &&
- bakedState->computedState.opaqueOverClippedBounds &&
- bakedState->computedState.clippedBounds.contains(repaintRect) &&
- !Properties::debugOverdraw)) {
- // discard all deferred drawing ops, since new one will occlude them
- clear();
- }
- }
-}
-
-void LayerBuilder::flushLayerClears(LinearAllocator& allocator) {
- if (CC_UNLIKELY(!mClearRects.empty())) {
- const int vertCount = mClearRects.size() * 4;
- // put the verts in the frame allocator, since
- // 1) SimpleRectsOps needs verts, not rects
- // 2) even if mClearRects stored verts, std::vectors will move their contents
- Vertex* const verts = (Vertex*)allocator.create_trivial_array<Vertex>(vertCount);
-
- Vertex* currentVert = verts;
- Rect bounds = mClearRects[0];
- for (auto&& rect : mClearRects) {
- bounds.unionWith(rect);
- Vertex::set(currentVert++, rect.left, rect.top);
- Vertex::set(currentVert++, rect.right, rect.top);
- Vertex::set(currentVert++, rect.left, rect.bottom);
- Vertex::set(currentVert++, rect.right, rect.bottom);
- }
- mClearRects.clear(); // discard rects before drawing so this method isn't reentrant
-
- // One or more unclipped saveLayers have been enqueued, with deferred clears.
- // Flush all of these clears with a single draw
- SkPaint* paint = allocator.create<SkPaint>();
- paint->setBlendMode(SkBlendMode::kClear);
- SimpleRectsOp* op = allocator.create_trivial<SimpleRectsOp>(
- bounds, Matrix4::identity(), nullptr, paint, verts, vertCount);
- BakedOpState* bakedState =
- BakedOpState::directConstruct(allocator, &repaintClip, bounds, *op);
- deferUnmergeableOp(allocator, bakedState, OpBatchType::Vertices);
- }
-}
-
-void LayerBuilder::deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op,
- batchid_t batchId) {
- onDeferOp(allocator, op);
- OpBatch* targetBatch = mBatchLookup[batchId];
-
- size_t insertBatchIndex = mBatches.size();
- if (targetBatch) {
- locateInsertIndex(batchId, op->computedState.clippedBounds, (BatchBase**)(&targetBatch),
- &insertBatchIndex);
- }
-
- if (targetBatch) {
- targetBatch->batchOp(op);
- } else {
- // new non-merging batch
- targetBatch = allocator.create<OpBatch>(batchId, op);
- mBatchLookup[batchId] = targetBatch;
- mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch);
- }
-}
-
-void LayerBuilder::deferMergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId,
- mergeid_t mergeId) {
- onDeferOp(allocator, op);
- MergingOpBatch* targetBatch = nullptr;
-
- // Try to merge with any existing batch with same mergeId
- auto getResult = mMergingBatchLookup[batchId].find(mergeId);
- if (getResult != mMergingBatchLookup[batchId].end()) {
- targetBatch = getResult->second;
- if (!targetBatch->canMergeWith(op)) {
- targetBatch = nullptr;
- }
- }
-
- size_t insertBatchIndex = mBatches.size();
- locateInsertIndex(batchId, op->computedState.clippedBounds, (BatchBase**)(&targetBatch),
- &insertBatchIndex);
-
- if (targetBatch) {
- targetBatch->mergeOp(op);
- } else {
- // new merging batch
- targetBatch = allocator.create<MergingOpBatch>(batchId, op);
- mMergingBatchLookup[batchId].insert(std::make_pair(mergeId, targetBatch));
-
- mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch);
- }
-}
-
-void LayerBuilder::replayBakedOpsImpl(void* arg, BakedOpReceiver* unmergedReceivers,
- MergedOpReceiver* mergedReceivers) const {
- if (renderNode) {
- ATRACE_FORMAT_BEGIN("Issue HW Layer DisplayList %s %ux%u", renderNode->getName(), width,
- height);
- } else {
- ATRACE_BEGIN("flush drawing commands");
- }
-
- for (const BatchBase* batch : mBatches) {
- size_t size = batch->getOps().size();
- if (size > 1 && batch->isMerging()) {
- int opId = batch->getOps()[0]->op->opId;
- const MergingOpBatch* mergingBatch = static_cast<const MergingOpBatch*>(batch);
- MergedBakedOpList data = {batch->getOps().data(), size,
- mergingBatch->getClipSideFlags(),
- mergingBatch->getClipRect()};
- mergedReceivers[opId](arg, data);
- } else {
- for (const BakedOpState* op : batch->getOps()) {
- unmergedReceivers[op->op->opId](arg, *op);
- }
- }
- }
- ATRACE_END();
-}
-
-void LayerBuilder::clear() {
- mBatches.clear();
- for (int i = 0; i < OpBatchType::Count; i++) {
- mBatchLookup[i] = nullptr;
- mMergingBatchLookup[i].clear();
- }
-}
-
-void LayerBuilder::dump() const {
- ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p (%s)", this, width, height,
- offscreenBuffer, beginLayerOp, renderNode, renderNode ? renderNode->getName() : "-");
- for (const BatchBase* batch : mBatches) {
- batch->dump();
- }
-}
-
-} // namespace uirenderer
-} // namespace android
diff --git a/libs/hwui/LayerBuilder.h b/libs/hwui/LayerBuilder.h
deleted file mode 100644
index c799d48..0000000
--- a/libs/hwui/LayerBuilder.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "ClipArea.h"
-#include "Rect.h"
-#include "utils/Macros.h"
-
-#include <unordered_map>
-#include <vector>
-
-struct SkRect;
-
-namespace android {
-namespace uirenderer {
-
-class BakedOpState;
-struct BeginLayerOp;
-class BatchBase;
-class LinearAllocator;
-struct MergedBakedOpList;
-class MergingOpBatch;
-class OffscreenBuffer;
-class OpBatch;
-class RenderNode;
-
-typedef int batchid_t;
-typedef const void* mergeid_t;
-
-namespace OpBatchType {
-enum {
- Bitmap,
- MergedPatch,
- AlphaVertices,
- Vertices,
- AlphaMaskTexture,
- Text,
- ColorText,
- Shadow,
- TextureLayer,
- Functor,
- CopyToLayer,
- CopyFromLayer,
-
- Count // must be last
-};
-}
-
-typedef void (*BakedOpReceiver)(void*, const BakedOpState&);
-typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList);
-
-/**
- * Stores the deferred render operations and state used to compute ordering
- * for a single FBO/layer.
- */
-class LayerBuilder {
- // Prevent copy/assign because users may stash pointer to offscreenBuffer and viewportClip
- PREVENT_COPY_AND_ASSIGN(LayerBuilder);
-
-public:
- // Create LayerBuilder for Fbo0
- LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect)
- : LayerBuilder(width, height, repaintRect, nullptr, nullptr){};
-
- // Create LayerBuilder for an offscreen layer, where beginLayerOp is present for a
- // saveLayer, renderNode is present for a HW layer.
- LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect,
- const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
-
- // iterate back toward target to see if anything drawn since should overlap the new op
- // if no target, merging ops still iterate to find similar batch to insert after
- void locateInsertIndex(int batchId, const Rect& clippedBounds, BatchBase** targetBatch,
- size_t* insertBatchIndex) const;
-
- void deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId);
-
- // insertion point of a new batch, will hopefully be immediately after similar batch
- // (generally, should be similar shader)
- void deferMergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId,
- mergeid_t mergeId);
-
- void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers, MergedOpReceiver*) const;
-
- void deferLayerClear(const Rect& dstRect);
-
- bool empty() const { return mBatches.empty(); }
-
- void clear();
-
- void dump() const;
-
- const uint32_t width;
- const uint32_t height;
- const Rect repaintRect;
- const ClipRect repaintClip;
- OffscreenBuffer* offscreenBuffer;
- const BeginLayerOp* beginLayerOp;
- const RenderNode* renderNode;
-
- // list of deferred CopyFromLayer ops, to be deferred upon encountering EndUnclippedLayerOps
- std::vector<BakedOpState*> activeUnclippedSaveLayers;
-
-private:
- void onDeferOp(LinearAllocator& allocator, const BakedOpState* bakedState);
- void flushLayerClears(LinearAllocator& allocator);
-
- std::vector<BatchBase*> mBatches;
-
- /**
- * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
- * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
- * collide, which avoids the need to resolve mergeid collisions.
- */
- std::unordered_map<mergeid_t, MergingOpBatch*> mMergingBatchLookup[OpBatchType::Count];
-
- // Maps batch ids to the most recent *non-merging* batch of that id
- OpBatch* mBatchLookup[OpBatchType::Count] = {nullptr};
-
- std::vector<Rect> mClearRects;
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/ProfileRenderer.cpp b/libs/hwui/ProfileRenderer.cpp
deleted file mode 100644
index 8a00ffa..0000000
--- a/libs/hwui/ProfileRenderer.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ProfileRenderer.h"
-
-namespace android {
-namespace uirenderer {
-
-void ProfileRenderer::drawRect(float left, float top, float right, float bottom,
- const SkPaint& paint) {
- mRenderer.drawRect(left, top, right, bottom, &paint);
-}
-
-void ProfileRenderer::drawRects(const float* rects, int count, const SkPaint& paint) {
- mRenderer.drawRects(rects, count, &paint);
-}
-
-uint32_t ProfileRenderer::getViewportWidth() {
- return mRenderer.getViewportWidth();
-}
-
-uint32_t ProfileRenderer::getViewportHeight() {
- return mRenderer.getViewportHeight();
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/ProfileRenderer.h b/libs/hwui/ProfileRenderer.h
deleted file mode 100644
index 5c8bb25..0000000
--- a/libs/hwui/ProfileRenderer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "IProfileRenderer.h"
-
-#include "BakedOpRenderer.h"
-
-namespace android {
-namespace uirenderer {
-
-class ProfileRenderer : public IProfileRenderer {
-public:
- ProfileRenderer(BakedOpRenderer& renderer) : mRenderer(renderer) {}
-
- void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
- void drawRects(const float* rects, int count, const SkPaint& paint) override;
- uint32_t getViewportWidth() override;
- uint32_t getViewportHeight() override;
-
- virtual ~ProfileRenderer() {}
-
-private:
- BakedOpRenderer& mRenderer;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index e903900..83fa84e 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -16,7 +16,6 @@
#include "RenderNode.h"
-#include "BakedOpRenderer.h"
#include "DamageAccumulator.h"
#include "Debug.h"
#include "RecordedOp.h"
diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
index 5ae7d6b..daa4c18 100644
--- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
+++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
@@ -16,7 +16,7 @@
#include "IProfileRenderer.h"
-#include "BakedOpRenderer.h"
+#include "SkCanvas.h"
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
deleted file mode 100644
index 08e18e0..0000000
--- a/libs/hwui/renderstate/Blend.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2015 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 <renderstate/Blend.h>
-#include "Program.h"
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Structure mapping Skia xfermodes to OpenGL blending factors.
- */
-struct Blender {
- SkBlendMode mode;
- GLenum src;
- GLenum dst;
-};
-
-// assumptions made by lookup tables in either this file or ProgramCache
-static_assert(0 == static_cast<int>(SkBlendMode::kClear), "SkBlendMode enums have changed");
-static_assert(1 == static_cast<int>(SkBlendMode::kSrc), "SkBlendMode enums have changed");
-static_assert(2 == static_cast<int>(SkBlendMode::kDst), "SkBlendMode enums have changed");
-static_assert(3 == static_cast<int>(SkBlendMode::kSrcOver), "SkBlendMode enums have changed");
-static_assert(4 == static_cast<int>(SkBlendMode::kDstOver), "SkBlendMode enums have changed");
-static_assert(5 == static_cast<int>(SkBlendMode::kSrcIn), "SkBlendMode enums have changed");
-static_assert(6 == static_cast<int>(SkBlendMode::kDstIn), "SkBlendMode enums have changed");
-static_assert(7 == static_cast<int>(SkBlendMode::kSrcOut), "SkBlendMode enums have changed");
-static_assert(8 == static_cast<int>(SkBlendMode::kDstOut), "SkBlendMode enums have changed");
-static_assert(9 == static_cast<int>(SkBlendMode::kSrcATop), "SkBlendMode enums have changed");
-static_assert(10 == static_cast<int>(SkBlendMode::kDstATop), "SkBlendMode enums have changed");
-static_assert(11 == static_cast<int>(SkBlendMode::kXor), "SkBlendMode enums have changed");
-static_assert(12 == static_cast<int>(SkBlendMode::kPlus), "SkBlendMode enums have changed");
-static_assert(13 == static_cast<int>(SkBlendMode::kModulate), "SkBlendMode enums have changed");
-static_assert(14 == static_cast<int>(SkBlendMode::kScreen), "SkBlendMode enums have changed");
-static_assert(15 == static_cast<int>(SkBlendMode::kOverlay), "SkBlendMode enums have changed");
-static_assert(16 == static_cast<int>(SkBlendMode::kDarken), "SkBlendMode enums have changed");
-static_assert(17 == static_cast<int>(SkBlendMode::kLighten), "SkBlendMode enums have changed");
-
-// In this array, the index of each Blender equals the value of the first
-// entry. For instance, gBlends[1] == gBlends[SkBlendMode::kSrc]
-const Blender kBlends[] = {{SkBlendMode::kClear, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kSrc, GL_ONE, GL_ZERO},
- {SkBlendMode::kDst, GL_ZERO, GL_ONE},
- {SkBlendMode::kSrcOver, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kDstOver, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
- {SkBlendMode::kSrcIn, GL_DST_ALPHA, GL_ZERO},
- {SkBlendMode::kDstIn, GL_ZERO, GL_SRC_ALPHA},
- {SkBlendMode::kSrcOut, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
- {SkBlendMode::kDstOut, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kSrcATop, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kDstATop, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
- {SkBlendMode::kXor, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kPlus, GL_ONE, GL_ONE},
- {SkBlendMode::kModulate, GL_ZERO, GL_SRC_COLOR},
- {SkBlendMode::kScreen, GL_ONE, GL_ONE_MINUS_SRC_COLOR}};
-
-// This array contains the swapped version of each SkBlendMode. For instance
-// this array's SrcOver blending mode is actually DstOver. You can refer to
-// createLayer() for more information on the purpose of this array.
-const Blender kBlendsSwap[] = {{SkBlendMode::kClear, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
- {SkBlendMode::kSrc, GL_ZERO, GL_ONE},
- {SkBlendMode::kDst, GL_ONE, GL_ZERO},
- {SkBlendMode::kSrcOver, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
- {SkBlendMode::kDstOver, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kSrcIn, GL_ZERO, GL_SRC_ALPHA},
- {SkBlendMode::kDstIn, GL_DST_ALPHA, GL_ZERO},
- {SkBlendMode::kSrcOut, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kDstOut, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
- {SkBlendMode::kSrcATop, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
- {SkBlendMode::kDstATop, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kXor, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
- {SkBlendMode::kPlus, GL_ONE, GL_ONE},
- {SkBlendMode::kModulate, GL_DST_COLOR, GL_ZERO},
- {SkBlendMode::kScreen, GL_ONE_MINUS_DST_COLOR, GL_ONE}};
-
-Blend::Blend() : mEnabled(false), mSrcMode(GL_ZERO), mDstMode(GL_ZERO) {
- // gl blending off by default
-}
-
-void Blend::invalidate() {
- syncEnabled();
- mSrcMode = mDstMode = GL_ZERO;
-}
-
-void Blend::syncEnabled() {
- if (mEnabled) {
- glEnable(GL_BLEND);
- } else {
- glDisable(GL_BLEND);
- }
-}
-
-void Blend::getFactors(SkBlendMode mode, ModeOrderSwap modeUsage, GLenum* outSrc, GLenum* outDst) {
- int index = static_cast<int>(mode);
- *outSrc = (modeUsage == ModeOrderSwap::Swap) ? kBlendsSwap[index].src : kBlends[index].src;
- *outDst = (modeUsage == ModeOrderSwap::Swap) ? kBlendsSwap[index].dst : kBlends[index].dst;
-}
-
-void Blend::setFactors(GLenum srcMode, GLenum dstMode) {
- if ((srcMode == GL_ZERO || srcMode == GL_ONE) && dstMode == GL_ZERO) {
- // disable blending
- if (mEnabled) {
- glDisable(GL_BLEND);
- mEnabled = false;
- }
- } else {
- // enable blending
- if (!mEnabled) {
- glEnable(GL_BLEND);
- mEnabled = true;
- }
-
- if (srcMode != mSrcMode || dstMode != mDstMode) {
- glBlendFunc(srcMode, dstMode);
- mSrcMode = srcMode;
- mDstMode = dstMode;
- }
- }
-}
-
-void Blend::dump() {
- ALOGD("Blend: enabled %d, func src %d, dst %d", mEnabled, mSrcMode, mDstMode);
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderstate/Blend.h b/libs/hwui/renderstate/Blend.h
deleted file mode 100644
index 7e559ba..0000000
--- a/libs/hwui/renderstate/Blend.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-#ifndef RENDERSTATE_BLEND_H
-#define RENDERSTATE_BLEND_H
-
-#include "Vertex.h"
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <SkBlendMode.h>
-#include <memory>
-
-namespace android {
-namespace uirenderer {
-
-class Blend {
- friend class RenderState;
-
-public:
- // dictates whether to swap src/dst
- enum class ModeOrderSwap {
- NoSwap,
- Swap,
- };
- void syncEnabled();
-
- static void getFactors(SkBlendMode mode, ModeOrderSwap modeUsage, GLenum* outSrc,
- GLenum* outDst);
- void setFactors(GLenum src, GLenum dst);
-
- bool getEnabled() { return mEnabled; }
- void getFactors(GLenum* src, GLenum* dst) {
- *src = mSrcMode;
- *dst = mDstMode;
- }
-
- void dump();
-
-private:
- Blend();
- void invalidate();
- bool mEnabled;
- GLenum mSrcMode;
- GLenum mDstMode;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif // RENDERSTATE_BLEND_H
diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp
deleted file mode 100644
index 4f6c49e..0000000
--- a/libs/hwui/renderstate/MeshState.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2015 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 "renderstate/MeshState.h"
-
-#include "Program.h"
-
-namespace android {
-namespace uirenderer {
-
-MeshState::MeshState()
- : mCurrentIndicesBuffer(0)
- , mCurrentPixelBuffer(0)
- , mCurrentPositionPointer(this)
- , mCurrentPositionStride(0)
- , mCurrentTexCoordsPointer(this)
- , mCurrentTexCoordsStride(0)
- , mTexCoordsArrayEnabled(false)
- , mQuadListIndices(0) {
- glGenBuffers(1, &mUnitQuadBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
- mCurrentBuffer = mUnitQuadBuffer;
-
- uint16_t regionIndices[kMaxNumberOfQuads * 6];
- for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
- uint16_t quad = i * 4;
- int index = i * 6;
- regionIndices[index] = quad; // top-left
- regionIndices[index + 1] = quad + 1; // top-right
- regionIndices[index + 2] = quad + 2; // bottom-left
- regionIndices[index + 3] = quad + 2; // bottom-left
- regionIndices[index + 4] = quad + 1; // top-right
- regionIndices[index + 5] = quad + 3; // bottom-right
- }
- glGenBuffers(1, &mQuadListIndices);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW);
- mCurrentIndicesBuffer = mQuadListIndices;
-
- // position attribute always enabled
- glEnableVertexAttribArray(Program::kBindingPosition);
-}
-
-MeshState::~MeshState() {
- glDeleteBuffers(1, &mUnitQuadBuffer);
- mCurrentBuffer = 0;
-
- glDeleteBuffers(1, &mQuadListIndices);
- mQuadListIndices = 0;
-}
-
-void MeshState::dump() {
- ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
- ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer);
- ALOGD("MeshState vertices: vertex data %p, stride %d", mCurrentPositionPointer,
- mCurrentPositionStride);
- ALOGD("MeshState texCoord: data %p, stride %d", mCurrentTexCoordsPointer,
- mCurrentTexCoordsStride);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Buffer Objects
-///////////////////////////////////////////////////////////////////////////////
-
-void MeshState::bindMeshBuffer(GLuint buffer) {
- if (mCurrentBuffer != buffer) {
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- mCurrentBuffer = buffer;
-
- // buffer has changed, so invalidate cached vertex pos/texcoord pointers
- resetVertexPointers();
- }
-}
-
-void MeshState::unbindMeshBuffer() {
- return bindMeshBuffer(0);
-}
-
-void MeshState::genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size, const void* data,
- GLenum usage) {
- if (!*buffer) {
- glGenBuffers(1, buffer);
- }
- bindMeshBuffer(*buffer);
- glBufferData(GL_ARRAY_BUFFER, size, data, usage);
-}
-
-void MeshState::updateMeshBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size,
- const void* data) {
- bindMeshBuffer(buffer);
- glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
-}
-
-void MeshState::deleteMeshBuffer(GLuint buffer) {
- if (buffer == mCurrentBuffer) {
- // GL defines that deleting the currently bound VBO rebinds to 0 (no VBO).
- // Reflect this in our cached value.
- mCurrentBuffer = 0;
- }
- glDeleteBuffers(1, &buffer);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Vertices
-///////////////////////////////////////////////////////////////////////////////
-
-void MeshState::bindPositionVertexPointer(const GLvoid* vertices, GLsizei stride) {
- // update pos coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
- if (mCurrentBuffer == 0 || vertices != mCurrentPositionPointer ||
- stride != mCurrentPositionStride) {
- glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
- mCurrentPositionPointer = vertices;
- mCurrentPositionStride = stride;
- }
-}
-
-void MeshState::bindTexCoordsVertexPointer(const GLvoid* vertices, GLsizei stride) {
- // update tex coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
- if (mCurrentBuffer == 0 || vertices != mCurrentTexCoordsPointer ||
- stride != mCurrentTexCoordsStride) {
- glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
- mCurrentTexCoordsPointer = vertices;
- mCurrentTexCoordsStride = stride;
- }
-}
-
-void MeshState::resetVertexPointers() {
- mCurrentPositionPointer = this;
- mCurrentTexCoordsPointer = this;
-}
-
-void MeshState::enableTexCoordsVertexArray() {
- if (!mTexCoordsArrayEnabled) {
- glEnableVertexAttribArray(Program::kBindingTexCoords);
- mCurrentTexCoordsPointer = this;
- mTexCoordsArrayEnabled = true;
- }
-}
-
-void MeshState::disableTexCoordsVertexArray() {
- if (mTexCoordsArrayEnabled) {
- glDisableVertexAttribArray(Program::kBindingTexCoords);
- mTexCoordsArrayEnabled = false;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Indices
-///////////////////////////////////////////////////////////////////////////////
-
-void MeshState::bindIndicesBuffer(const GLuint buffer) {
- if (mCurrentIndicesBuffer != buffer) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
- mCurrentIndicesBuffer = buffer;
- }
-}
-
-void MeshState::unbindIndicesBuffer() {
- if (mCurrentIndicesBuffer) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- mCurrentIndicesBuffer = 0;
- }
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h
deleted file mode 100644
index 95faf1e..0000000
--- a/libs/hwui/renderstate/MeshState.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-#ifndef RENDERSTATE_MESHSTATE_H
-#define RENDERSTATE_MESHSTATE_H
-
-#include "Vertex.h"
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <memory>
-
-namespace android {
-namespace uirenderer {
-
-class Program;
-
-// Maximum number of quads that pre-allocated meshes can draw
-const uint32_t kMaxNumberOfQuads = 2048;
-
-// This array is never used directly but used as a memcpy source in the
-// OpenGLRenderer constructor
-const TextureVertex kUnitQuadVertices[] = {
- {0, 0, 0, 0}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 1, 1, 1},
-};
-
-const GLsizei kVertexStride = sizeof(Vertex);
-const GLsizei kAlphaVertexStride = sizeof(AlphaVertex);
-const GLsizei kTextureVertexStride = sizeof(TextureVertex);
-const GLsizei kColorTextureVertexStride = sizeof(ColorTextureVertex);
-
-const GLsizei kMeshTextureOffset = 2 * sizeof(float);
-const GLsizei kVertexAlphaOffset = 2 * sizeof(float);
-const GLsizei kVertexAAWidthOffset = 2 * sizeof(float);
-const GLsizei kVertexAALengthOffset = 3 * sizeof(float);
-const GLsizei kUnitQuadCount = 4;
-
-class MeshState {
-private:
- friend class RenderState;
-
-public:
- ~MeshState();
- void dump();
- ///////////////////////////////////////////////////////////////////////////////
- // Buffer objects
- ///////////////////////////////////////////////////////////////////////////////
-
- /**
- * Binds the specified VBO if needed. If buffer == 0, binds default simple textured quad.
- */
- void bindMeshBuffer(GLuint buffer);
-
- /**
- * Unbinds the current VBO if active.
- */
- void unbindMeshBuffer();
-
- void genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size, const void* data, GLenum usage);
- void updateMeshBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data);
- void deleteMeshBuffer(GLuint);
-
- ///////////////////////////////////////////////////////////////////////////////
- // Vertices
- ///////////////////////////////////////////////////////////////////////////////
- /**
- * Binds an attrib to the specified float vertex pointer.
- * Assumes a stride of gTextureVertexStride and a size of 2.
- */
- void bindPositionVertexPointer(const GLvoid* vertices, GLsizei stride = kTextureVertexStride);
-
- /**
- * Binds an attrib to the specified float vertex pointer.
- * Assumes a stride of gTextureVertexStride and a size of 2.
- */
- void bindTexCoordsVertexPointer(const GLvoid* vertices, GLsizei stride = kTextureVertexStride);
-
- /**
- * Resets the vertex pointers.
- */
- void resetVertexPointers();
-
- void enableTexCoordsVertexArray();
- void disableTexCoordsVertexArray();
-
- ///////////////////////////////////////////////////////////////////////////////
- // Indices
- ///////////////////////////////////////////////////////////////////////////////
- void bindIndicesBuffer(const GLuint buffer);
- void unbindIndicesBuffer();
-
- ///////////////////////////////////////////////////////////////////////////////
- // Getters - for use in Glop building
- ///////////////////////////////////////////////////////////////////////////////
- GLuint getUnitQuadVBO() { return mUnitQuadBuffer; }
- GLuint getQuadListIBO() { return mQuadListIndices; }
-
-private:
- MeshState();
-
- GLuint mUnitQuadBuffer;
-
- GLuint mCurrentBuffer;
- GLuint mCurrentIndicesBuffer;
- GLuint mCurrentPixelBuffer;
-
- const void* mCurrentPositionPointer;
- GLsizei mCurrentPositionStride;
- const void* mCurrentTexCoordsPointer;
- GLsizei mCurrentTexCoordsStride;
-
- bool mTexCoordsArrayEnabled;
-
- // Global index buffer
- GLuint mQuadListIndices;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif // RENDERSTATE_MESHSTATE_H
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index a0f5cb9..e148ebd 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -67,37 +67,7 @@
}
void OffscreenBuffer::updateMeshFromRegion() {
- // avoid T-junctions as they cause artifacts in between the resultant
- // geometry when complex transforms occur.
- // TODO: generate the safeRegion only if necessary based on drawing transform
- Region safeRegion = Region::createTJunctionFreeRegion(region);
-
- size_t count;
- const android::Rect* rects = safeRegion.getArray(&count);
-
- const float texX = 1.0f / float(texture.width());
- const float texY = 1.0f / float(texture.height());
-
- FatVector<TextureVertex, 64> meshVector(count *
- 4); // uses heap if more than 64 vertices needed
- TextureVertex* mesh = &meshVector[0];
- for (size_t i = 0; i < count; i++) {
- const android::Rect* r = &rects[i];
-
- const float u1 = r->left * texX;
- const float v1 = (viewportHeight - r->top) * texY;
- const float u2 = r->right * texX;
- const float v2 = (viewportHeight - r->bottom) * texY;
-
- TextureVertex::set(mesh++, r->left, r->top, u1, v1);
- TextureVertex::set(mesh++, r->right, r->top, u2, v1);
- TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
- TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
- }
- elementCount = count * 6;
- renderState.meshState().genOrUpdateMeshBuffer(
- &vbo, sizeof(TextureVertex) * count * 4, &meshVector[0],
- GL_DYNAMIC_DRAW); // TODO: GL_STATIC_DRAW if savelayer
+ // DEAD CODE
}
uint32_t OffscreenBuffer::computeIdealDimension(uint32_t dimension) {
@@ -105,11 +75,7 @@
}
OffscreenBuffer::~OffscreenBuffer() {
- ATRACE_FORMAT("Destroy %ux%u HW Layer", texture.width(), texture.height());
- texture.deleteTexture();
- renderState.meshState().deleteMeshBuffer(vbo);
- elementCount = 0;
- vbo = 0;
+ // DEAD CODE
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index a60e2b5..a1c8dca 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -37,20 +37,11 @@
}
RenderState::~RenderState() {
- LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
- "State object lifecycle not managed correctly");
}
void RenderState::onGLContextCreated() {
- LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
- "State object lifecycle not managed correctly");
GpuMemoryTracker::onGpuContextCreated();
- mBlend = new Blend();
- mMeshState = new MeshState();
- mScissor = new Scissor();
- mStencil = new Stencil();
-
// Deferred because creation needs GL context for texture limits
if (!mLayerPool) {
mLayerPool = new OffscreenBufferPool();
@@ -77,22 +68,11 @@
mCaches->terminate();
- delete mBlend;
- mBlend = nullptr;
- delete mMeshState;
- mMeshState = nullptr;
- delete mScissor;
- mScissor = nullptr;
- delete mStencil;
- mStencil = nullptr;
-
destroyLayersInUpdater();
GpuMemoryTracker::onGpuContextDestroyed();
}
void RenderState::onVkContextCreated() {
- LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
- "State object lifecycle not managed correctly");
GpuMemoryTracker::onGpuContextCreated();
}
@@ -177,10 +157,6 @@
void RenderState::interruptForFunctorInvoke() {
mCaches->setProgram(nullptr);
mCaches->textureState().resetActiveTexture();
- meshState().unbindMeshBuffer();
- meshState().unbindIndicesBuffer();
- meshState().resetVertexPointers();
- meshState().disableTexCoordsVertexArray();
debugOverdraw(false, false);
// TODO: We need a way to know whether the functor is sRGB aware (b/32072673)
if (mCaches->extensions().hasLinearBlending() && mCaches->extensions().hasSRGBWriteControl()) {
@@ -199,25 +175,12 @@
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- scissor().invalidate();
- blend().invalidate();
-
mCaches->textureState().activateTexture(0);
mCaches->textureState().resetBoundTextures();
}
void RenderState::debugOverdraw(bool enable, bool clear) {
- if (Properties::debugOverdraw && mFramebuffer == 0) {
- if (clear) {
- scissor().setEnabled(false);
- stencil().clear();
- }
- if (enable) {
- stencil().enableDebugWrite();
- } else {
- stencil().disable();
- }
- }
+ // DEAD CODE
}
static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
@@ -242,9 +205,6 @@
void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix,
bool overrideDisableBlending) {
- const Glop::Mesh& mesh = glop.mesh;
- const Glop::Mesh::Vertices& vertices = mesh.vertices;
- const Glop::Mesh::Indices& indices = mesh.indices;
const Glop::Fill& fill = glop.fill;
GL_CHECKPOINT(MODERATE);
@@ -297,16 +257,6 @@
GL_CHECKPOINT(MODERATE);
- // --------------------------------
- // ---------- Mesh setup ----------
- // --------------------------------
- // vertices
- meshState().bindMeshBuffer(vertices.bufferObject);
- meshState().bindPositionVertexPointer(vertices.position, vertices.stride);
-
- // indices
- meshState().bindIndicesBuffer(indices.bufferObject);
-
// texture
if (fill.texture.texture != nullptr) {
const Glop::Fill::TextureData& texture = fill.texture;
@@ -327,28 +277,6 @@
}
}
- // vertex attributes (tex coord, color, alpha)
- if (vertices.attribFlags & VertexAttribFlags::TextureCoord) {
- meshState().enableTexCoordsVertexArray();
- meshState().bindTexCoordsVertexPointer(vertices.texCoord, vertices.stride);
- } else {
- meshState().disableTexCoordsVertexArray();
- }
- int colorLocation = -1;
- if (vertices.attribFlags & VertexAttribFlags::Color) {
- colorLocation = fill.program->getAttrib("colors");
- glEnableVertexAttribArray(colorLocation);
- glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride,
- vertices.color);
- }
- int alphaLocation = -1;
- if (vertices.attribFlags & VertexAttribFlags::Alpha) {
- // NOTE: alpha vertex position is computed assuming no VBO
- const void* alphaCoords = ((const GLbyte*)vertices.position) + kVertexAlphaOffset;
- alphaLocation = fill.program->getAttrib("vtxAlpha");
- glEnableVertexAttribArray(alphaLocation);
- glVertexAttribPointer(alphaLocation, 1, GL_FLOAT, GL_FALSE, vertices.stride, alphaCoords);
- }
// Shader uniforms
SkiaShader::apply(*mCaches, fill.skiaShaderData, mViewportWidth, mViewportHeight);
@@ -392,77 +320,11 @@
}
}
- // ------------------------------------
- // ---------- GL state setup ----------
- // ------------------------------------
- if (CC_UNLIKELY(overrideDisableBlending)) {
- blend().setFactors(GL_ZERO, GL_ZERO);
- } else {
- blend().setFactors(glop.blend.src, glop.blend.dst);
- }
-
- GL_CHECKPOINT(MODERATE);
-
- // ------------------------------------
- // ---------- Actual drawing ----------
- // ------------------------------------
- if (indices.bufferObject == meshState().getQuadListIBO()) {
- // Since the indexed quad list is of limited length, we loop over
- // the glDrawXXX method while updating the vertex pointer
- GLsizei elementsCount = mesh.elementCount;
- const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position);
- while (elementsCount > 0) {
- GLsizei drawCount = std::min(elementsCount, (GLsizei)kMaxNumberOfQuads * 6);
- GLsizei vertexCount = (drawCount / 6) * 4;
- meshState().bindPositionVertexPointer(vertexData, vertices.stride);
- if (vertices.attribFlags & VertexAttribFlags::TextureCoord) {
- meshState().bindTexCoordsVertexPointer(vertexData + kMeshTextureOffset,
- vertices.stride);
- }
-
- if (mCaches->extensions().getMajorGlVersion() >= 3) {
- glDrawRangeElements(mesh.primitiveMode, 0, vertexCount - 1, drawCount,
- GL_UNSIGNED_SHORT, nullptr);
- } else {
- glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr);
- }
- elementsCount -= drawCount;
- vertexData += vertexCount * vertices.stride;
- }
- } else if (indices.bufferObject || indices.indices) {
- if (mCaches->extensions().getMajorGlVersion() >= 3) {
- // use glDrawRangeElements to reduce CPU overhead (otherwise the driver has to determine
- // the min/max index values)
- glDrawRangeElements(mesh.primitiveMode, 0, mesh.vertexCount - 1, mesh.elementCount,
- GL_UNSIGNED_SHORT, indices.indices);
- } else {
- glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT,
- indices.indices);
- }
- } else {
- glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount);
- }
-
- GL_CHECKPOINT(MODERATE);
-
- // -----------------------------------
- // ---------- Mesh teardown ----------
- // -----------------------------------
- if (vertices.attribFlags & VertexAttribFlags::Alpha) {
- glDisableVertexAttribArray(alphaLocation);
- }
- if (vertices.attribFlags & VertexAttribFlags::Color) {
- glDisableVertexAttribArray(colorLocation);
- }
-
GL_CHECKPOINT(MODERATE);
}
void RenderState::dump() {
- blend().dump();
- meshState().dump();
- scissor().dump();
- stencil().dump();
+ // DEAD CODE
}
} /* namespace uirenderer */
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index e033cf2..189ddc1 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -18,12 +18,8 @@
#include "Caches.h"
#include "Glop.h"
-#include "renderstate/Blend.h"
-#include "renderstate/MeshState.h"
#include "renderstate/OffscreenBufferPool.h"
#include "renderstate/PixelBufferState.h"
-#include "renderstate/Scissor.h"
-#include "renderstate/Stencil.h"
#include "utils/Macros.h"
#include <GLES2/gl2.h>
@@ -105,11 +101,6 @@
void render(const Glop& glop, const Matrix4& orthoMatrix, bool overrideDisableBlending);
- Blend& blend() { return *mBlend; }
- MeshState& meshState() { return *mMeshState; }
- Scissor& scissor() { return *mScissor; }
- Stencil& stencil() { return *mStencil; }
-
OffscreenBufferPool& layerPool() { return *mLayerPool; }
GrContext* getGrContext() const;
@@ -127,11 +118,6 @@
renderthread::RenderThread& mRenderThread;
Caches* mCaches = nullptr;
- Blend* mBlend = nullptr;
- MeshState* mMeshState = nullptr;
- Scissor* mScissor = nullptr;
- Stencil* mStencil = nullptr;
-
OffscreenBufferPool* mLayerPool = nullptr;
std::set<Layer*> mActiveLayers;
diff --git a/libs/hwui/renderstate/Scissor.cpp b/libs/hwui/renderstate/Scissor.cpp
deleted file mode 100644
index e37ed02..0000000
--- a/libs/hwui/renderstate/Scissor.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2015 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 "renderstate/Scissor.h"
-
-#include "Rect.h"
-
-#include <utils/Log.h>
-
-namespace android {
-namespace uirenderer {
-
-Scissor::Scissor()
- : mEnabled(false), mScissorX(0), mScissorY(0), mScissorWidth(0), mScissorHeight(0) {}
-
-bool Scissor::setEnabled(bool enabled) {
- if (mEnabled != enabled) {
- if (enabled) {
- glEnable(GL_SCISSOR_TEST);
- } else {
- glDisable(GL_SCISSOR_TEST);
- }
- mEnabled = enabled;
- return true;
- }
- return false;
-}
-
-bool Scissor::set(GLint x, GLint y, GLint width, GLint height) {
- if (mEnabled &&
- (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight)) {
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (y < 0) {
- height += y;
- y = 0;
- }
- if (width < 0) {
- width = 0;
- }
- if (height < 0) {
- height = 0;
- }
- glScissor(x, y, width, height);
-
- mScissorX = x;
- mScissorY = y;
- mScissorWidth = width;
- mScissorHeight = height;
-
- return true;
- }
- return false;
-}
-
-void Scissor::set(int viewportHeight, const Rect& clip) {
- // transform to Y-flipped GL space, and prevent negatives
- GLint x = std::max(0, (int)clip.left);
- GLint y = std::max(0, viewportHeight - (int)clip.bottom);
- GLint width = std::max(0, ((int)clip.right) - x);
- GLint height = std::max(0, (viewportHeight - (int)clip.top) - y);
-
- if (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight) {
- glScissor(x, y, width, height);
-
- mScissorX = x;
- mScissorY = y;
- mScissorWidth = width;
- mScissorHeight = height;
- }
-}
-
-void Scissor::reset() {
- mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
-}
-
-void Scissor::invalidate() {
- mEnabled = glIsEnabled(GL_SCISSOR_TEST);
- setEnabled(true);
- reset();
-}
-
-void Scissor::dump() {
- ALOGD("Scissor: enabled %d, %d %d %d %d", mEnabled, mScissorX, mScissorY, mScissorWidth,
- mScissorHeight);
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderstate/Scissor.h b/libs/hwui/renderstate/Scissor.h
deleted file mode 100644
index 2b04f4e..0000000
--- a/libs/hwui/renderstate/Scissor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-#ifndef RENDERSTATE_SCISSOR_H
-#define RENDERSTATE_SCISSOR_H
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-namespace android {
-namespace uirenderer {
-
-class Rect;
-
-class Scissor {
- friend class RenderState;
-
-public:
- bool setEnabled(bool enabled);
- bool set(GLint x, GLint y, GLint width, GLint height);
- void set(int viewportHeight, const Rect& clip);
- void reset();
- bool isEnabled() { return mEnabled; }
- void dump();
-
-private:
- Scissor();
- void invalidate();
- bool mEnabled;
- GLint mScissorX;
- GLint mScissorY;
- GLint mScissorWidth;
- GLint mScissorHeight;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif // RENDERSTATE_SCISSOR_H
diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp
deleted file mode 100644
index dc465fc..0000000
--- a/libs/hwui/renderstate/Stencil.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 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 "renderstate/Stencil.h"
-
-#include "Caches.h"
-#include "Debug.h"
-#include "Extensions.h"
-#include "Properties.h"
-
-#include <GLES2/gl2ext.h>
-
-namespace android {
-namespace uirenderer {
-
-#if DEBUG_STENCIL
-#define STENCIL_WRITE_VALUE 0xff
-#define STENCIL_MASK_VALUE 0xff
-#else
-#define STENCIL_WRITE_VALUE 0x1
-#define STENCIL_MASK_VALUE 0x1
-#endif
-
-uint8_t Stencil::getStencilSize() {
- return STENCIL_BUFFER_SIZE;
-}
-
-/**
- * This method will return either GL_STENCIL_INDEX4_OES if supported,
- * GL_STENCIL_INDEX8 if not.
- *
- * Layers can't use a single bit stencil because multi-rect ClipArea needs a high enough
- * stencil resolution to represent the summation of multiple intersecting rect geometries.
- */
-GLenum Stencil::getLayerStencilFormat() {
-#if !DEBUG_STENCIL
- const Extensions& extensions = DeviceInfo::get()->extensions();
- if (extensions.has4BitStencil()) {
- return GL_STENCIL_INDEX4_OES;
- }
-#endif
- return GL_STENCIL_INDEX8;
-}
-
-void Stencil::clear() {
- glStencilMask(0xff);
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
-
- if (mState == StencilState::Test) {
- // reset to test state, with immutable stencil
- glStencilMask(0);
- }
-}
-
-void Stencil::enableTest(int incrementThreshold) {
- if (mState != StencilState::Test) {
- enable();
- if (incrementThreshold > 0) {
- glStencilFunc(GL_EQUAL, incrementThreshold, 0xff);
- } else {
- glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
- }
- // We only want to test, let's keep everything
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilMask(0);
- mState = StencilState::Test;
- }
-}
-
-void Stencil::enableWrite(int incrementThreshold) {
- if (mState != StencilState::Write) {
- enable();
- if (incrementThreshold > 0) {
- glStencilFunc(GL_ALWAYS, 1, 0xff);
- // The test always passes so the first two values are meaningless
- glStencilOp(GL_INCR, GL_INCR, GL_INCR);
- } else {
- glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
- // The test always passes so the first two values are meaningless
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- }
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- glStencilMask(0xff);
- mState = StencilState::Write;
- }
-}
-
-void Stencil::enableDebugTest(GLint value, bool greater) {
- enable();
- glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
- // We only want to test, let's keep everything
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- mState = StencilState::Test;
- glStencilMask(0);
-}
-
-void Stencil::enableDebugWrite() {
- enable();
- glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
- // The test always passes so the first two values are meaningless
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- mState = StencilState::Write;
- glStencilMask(0xff);
-}
-
-void Stencil::enable() {
- if (mState == StencilState::Disabled) {
- glEnable(GL_STENCIL_TEST);
- }
-}
-
-void Stencil::disable() {
- if (mState != StencilState::Disabled) {
- glDisable(GL_STENCIL_TEST);
- mState = StencilState::Disabled;
- }
-}
-
-void Stencil::dump() {
- ALOGD("Stencil: state %d", mState);
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/renderstate/Stencil.h b/libs/hwui/renderstate/Stencil.h
deleted file mode 100644
index 95f3723..0000000
--- a/libs/hwui/renderstate/Stencil.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ANDROID_HWUI_STENCIL_H
-#define ANDROID_HWUI_STENCIL_H
-
-#include <GLES2/gl2.h>
-
-#include <cutils/compiler.h>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Stencil buffer management
-///////////////////////////////////////////////////////////////////////////////
-
-class ANDROID_API Stencil {
-public:
- /**
- * Returns the desired size for the stencil buffer. If the returned value
- * is 0, then no stencil buffer is required.
- */
- ANDROID_API static uint8_t getStencilSize();
-
- static GLenum getLayerStencilFormat();
-
- /**
- * Clears the stencil buffer.
- */
- void clear();
-
- /**
- * Enables stencil test. When the stencil test is enabled the stencil buffer is not written
- * into. An increment threshold of zero causes the stencil to use a constant reference value
- * and GL_EQUAL for the test. A non-zero increment threshold causes the stencil to use that
- * value as the reference value and GL_EQUAL for the test.
- */
- void enableTest(int incrementThreshold);
-
- /**
- * Enables stencil write. When stencil write is enabled, the stencil
- * test always succeeds and the value 0x1 is written in the stencil
- * buffer for each fragment. An increment threshold of zero causes the stencil to use a constant
- * reference value and GL_EQUAL for the test. A non-zero increment threshold causes the stencil
- * to use that value as the reference value and GL_EQUAL for the test.
- */
- void enableWrite(int incrementThreshold);
-
- /**
- * The test passes only when equal to the specified value.
- */
- void enableDebugTest(GLint value, bool greater = false);
-
- /**
- * Used for debugging. The stencil test always passes and increments.
- */
- void enableDebugWrite();
-
- /**
- * Disables stencil test and write.
- */
- void disable();
-
- /**
- * Indicates whether either test or write is enabled.
- */
- bool isEnabled() { return mState != StencilState::Disabled; }
-
- /**
- * Indicates whether testing only is enabled.
- */
- bool isTestEnabled() { return mState == StencilState::Test; }
-
- bool isWriteEnabled() { return mState == StencilState::Write; }
-
- void dump();
-
-private:
- enum class StencilState { Disabled, Test, Write };
-
- void enable();
- StencilState mState = StencilState::Disabled;
-
-}; // class Stencil
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_STENCIL_H
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a36dae4..96920dd 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -29,7 +29,6 @@
#include "pipeline/skia/SkiaPipeline.h"
#include "pipeline/skia/SkiaVulkanPipeline.h"
#include "renderstate/RenderState.h"
-#include "renderstate/Stencil.h"
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
#include "../Properties.h"