remove unneeded RecordedOps
Test: make Change-Id: Ifcb0df64ad649623ae875462f55d9009a4e1ac03
This commit is contained in:
@@ -206,15 +206,12 @@ cc_defaults {
|
||||
"FrameInfoVisualizer.cpp",
|
||||
"GlLayer.cpp",
|
||||
"GpuMemoryTracker.cpp",
|
||||
"Image.cpp",
|
||||
"Interpolator.cpp",
|
||||
"JankTracker.cpp",
|
||||
"Layer.cpp",
|
||||
"LayerUpdateQueue.cpp",
|
||||
"Matrix.cpp",
|
||||
"OpDumper.cpp",
|
||||
"EglReadback.cpp",
|
||||
"Patch.cpp",
|
||||
"PathParser.cpp",
|
||||
"PixelBuffer.cpp",
|
||||
"ProfileData.cpp",
|
||||
@@ -318,7 +315,6 @@ cc_test {
|
||||
"tests/unit/LayerUpdateQueueTests.cpp",
|
||||
"tests/unit/LinearAllocatorTests.cpp",
|
||||
"tests/unit/MatrixTests.cpp",
|
||||
"tests/unit/OpDumperTests.cpp",
|
||||
"tests/unit/PathInterpolatorTests.cpp",
|
||||
"tests/unit/RenderNodeDrawableTests.cpp",
|
||||
"tests/unit/RenderNodeTests.cpp",
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 <utils/Log.h>
|
||||
|
||||
#include "Caches.h"
|
||||
#include "Image.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
Image::Image(sp<GraphicBuffer> buffer) {
|
||||
// Create the EGLImage object that maps the GraphicBuffer
|
||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
EGLClientBuffer clientBuffer = (EGLClientBuffer)buffer->getNativeBuffer();
|
||||
EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
|
||||
|
||||
mImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer,
|
||||
attrs);
|
||||
|
||||
if (mImage == EGL_NO_IMAGE_KHR) {
|
||||
ALOGW("Error creating image (%#x)", eglGetError());
|
||||
mTexture = 0;
|
||||
} else {
|
||||
// Create a 2D texture to sample from the EGLImage
|
||||
glGenTextures(1, &mTexture);
|
||||
Caches::getInstance().textureState().bindTexture(mTexture);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
|
||||
|
||||
GLenum status = GL_NO_ERROR;
|
||||
while ((status = glGetError()) != GL_NO_ERROR) {
|
||||
ALOGW("Error creating image (%#x)", status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image::~Image() {
|
||||
if (mImage != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), mImage);
|
||||
mImage = EGL_NO_IMAGE_KHR;
|
||||
|
||||
Caches::getInstance().textureState().deleteTexture(mTexture);
|
||||
mTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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_IMAGE_H
|
||||
#define ANDROID_HWUI_IMAGE_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
/**
|
||||
* A simple wrapper that creates an EGLImage and a texture for a GraphicBuffer.
|
||||
*/
|
||||
class Image {
|
||||
public:
|
||||
/**
|
||||
* Creates a new image from the specified graphic buffer. If the image
|
||||
* cannot be created, getTexture() will return 0 and getImage() will
|
||||
* return EGL_NO_IMAGE_KHR.
|
||||
*/
|
||||
explicit Image(sp<GraphicBuffer> buffer);
|
||||
~Image();
|
||||
|
||||
/**
|
||||
* Returns the name of the GL texture that can be used to sample
|
||||
* from this image.
|
||||
*/
|
||||
GLuint getTexture() const { return mTexture; }
|
||||
|
||||
/**
|
||||
* Returns the name of the EGL image represented by this object.
|
||||
*/
|
||||
EGLImageKHR getImage() const { return mImage; }
|
||||
|
||||
private:
|
||||
GLuint mTexture;
|
||||
EGLImageKHR mImage;
|
||||
}; // class Image
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_HWUI_IMAGE_H
|
||||
@@ -1,53 +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 "OpDumper.h"
|
||||
|
||||
#include "ClipArea.h"
|
||||
#include "RecordedOp.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
#define STRINGIFY(n) #n,
|
||||
static const char* sOpNameLut[] = BUILD_FULL_OP_LUT(STRINGIFY);
|
||||
|
||||
void OpDumper::dump(const RecordedOp& op, std::ostream& output, int level) {
|
||||
for (int i = 0; i < level; i++) {
|
||||
output << " ";
|
||||
}
|
||||
|
||||
Rect localBounds(op.unmappedBounds);
|
||||
op.localMatrix.mapRect(localBounds);
|
||||
output << sOpNameLut[op.opId] << " " << localBounds;
|
||||
|
||||
if (op.localClip &&
|
||||
(!op.localClip->rect.contains(localBounds) || op.localClip->intersectWithRoot)) {
|
||||
output << std::fixed << std::setprecision(0) << " clip=" << op.localClip->rect
|
||||
<< " mode=" << (int)op.localClip->mode;
|
||||
|
||||
if (op.localClip->intersectWithRoot) {
|
||||
output << " iwr";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* OpDumper::opName(const RecordedOp& op) {
|
||||
return sOpNameLut[op.opId];
|
||||
}
|
||||
|
||||
} // namespace uirenderer
|
||||
} // namespace android
|
||||
@@ -1,33 +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 <ostream>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
struct RecordedOp;
|
||||
|
||||
class OpDumper {
|
||||
public:
|
||||
static void dump(const RecordedOp& op, std::ostream& output, int level = 0);
|
||||
static const char* opName(const RecordedOp& op);
|
||||
};
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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 "Patch.h"
|
||||
|
||||
#include "Caches.h"
|
||||
#include "Properties.h"
|
||||
#include "UvMapper.h"
|
||||
#include "utils/MathUtils.h"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Vertices management
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t Patch::getSize() const {
|
||||
return verticesCount * sizeof(TextureVertex);
|
||||
}
|
||||
|
||||
Patch::Patch(const float bitmapWidth, const float bitmapHeight, float width, float height,
|
||||
const UvMapper& mapper, const Res_png_9patch* patch)
|
||||
: mColors(patch->getColors()) {
|
||||
int8_t emptyQuads = 0;
|
||||
const int8_t numColors = patch->numColors;
|
||||
if (uint8_t(numColors) < sizeof(uint32_t) * 4) {
|
||||
for (int8_t i = 0; i < numColors; i++) {
|
||||
if (mColors[i] == 0x0) {
|
||||
emptyQuads++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasEmptyQuads = emptyQuads > 0;
|
||||
|
||||
uint32_t xCount = patch->numXDivs;
|
||||
uint32_t yCount = patch->numYDivs;
|
||||
|
||||
uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 4;
|
||||
if (maxVertices == 0) return;
|
||||
|
||||
vertices.reset(new TextureVertex[maxVertices]);
|
||||
TextureVertex* vertex = vertices.get();
|
||||
|
||||
const int32_t* xDivs = patch->getXDivs();
|
||||
const int32_t* yDivs = patch->getYDivs();
|
||||
|
||||
const uint32_t xStretchCount = (xCount + 1) >> 1;
|
||||
const uint32_t yStretchCount = (yCount + 1) >> 1;
|
||||
|
||||
float stretchX = 0.0f;
|
||||
float stretchY = 0.0f;
|
||||
|
||||
float rescaleX = 1.0f;
|
||||
float rescaleY = 1.0f;
|
||||
|
||||
if (xStretchCount > 0) {
|
||||
uint32_t stretchSize = 0;
|
||||
for (uint32_t i = 1; i < xCount; i += 2) {
|
||||
stretchSize += xDivs[i] - xDivs[i - 1];
|
||||
}
|
||||
const float xStretchTex = stretchSize;
|
||||
const float fixed = bitmapWidth - stretchSize;
|
||||
const float xStretch = std::max(width - fixed, 0.0f);
|
||||
stretchX = xStretch / xStretchTex;
|
||||
rescaleX = fixed == 0.0f ? 0.0f : std::min(std::max(width, 0.0f) / fixed, 1.0f);
|
||||
}
|
||||
|
||||
if (yStretchCount > 0) {
|
||||
uint32_t stretchSize = 0;
|
||||
for (uint32_t i = 1; i < yCount; i += 2) {
|
||||
stretchSize += yDivs[i] - yDivs[i - 1];
|
||||
}
|
||||
const float yStretchTex = stretchSize;
|
||||
const float fixed = bitmapHeight - stretchSize;
|
||||
const float yStretch = std::max(height - fixed, 0.0f);
|
||||
stretchY = yStretch / yStretchTex;
|
||||
rescaleY = fixed == 0.0f ? 0.0f : std::min(std::max(height, 0.0f) / fixed, 1.0f);
|
||||
}
|
||||
|
||||
uint32_t quadCount = 0;
|
||||
|
||||
float previousStepY = 0.0f;
|
||||
|
||||
float y1 = 0.0f;
|
||||
float y2 = 0.0f;
|
||||
float v1 = 0.0f;
|
||||
|
||||
mUvMapper = mapper;
|
||||
|
||||
for (uint32_t i = 0; i < yCount; i++) {
|
||||
float stepY = yDivs[i];
|
||||
const float segment = stepY - previousStepY;
|
||||
|
||||
if (i & 1) {
|
||||
y2 = y1 + floorf(segment * stretchY + 0.5f);
|
||||
} else {
|
||||
y2 = y1 + segment * rescaleY;
|
||||
}
|
||||
|
||||
float vOffset = y1 == y2 ? 0.0f : 0.5 - (0.5 * segment / (y2 - y1));
|
||||
float v2 = std::max(0.0f, stepY - vOffset) / bitmapHeight;
|
||||
v1 += vOffset / bitmapHeight;
|
||||
|
||||
if (stepY > 0.0f) {
|
||||
generateRow(xDivs, xCount, vertex, y1, y2, v1, v2, stretchX, rescaleX, width,
|
||||
bitmapWidth, quadCount);
|
||||
}
|
||||
|
||||
y1 = y2;
|
||||
v1 = stepY / bitmapHeight;
|
||||
|
||||
previousStepY = stepY;
|
||||
}
|
||||
|
||||
if (previousStepY != bitmapHeight) {
|
||||
y2 = height;
|
||||
generateRow(xDivs, xCount, vertex, y1, y2, v1, 1.0f, stretchX, rescaleX, width, bitmapWidth,
|
||||
quadCount);
|
||||
}
|
||||
|
||||
if (verticesCount != maxVertices) {
|
||||
std::unique_ptr<TextureVertex[]> reducedVertices(new TextureVertex[verticesCount]);
|
||||
memcpy(reducedVertices.get(), vertices.get(), verticesCount * sizeof(TextureVertex));
|
||||
vertices = std::move(reducedVertices);
|
||||
}
|
||||
}
|
||||
|
||||
void Patch::generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex, float y1,
|
||||
float y2, float v1, float v2, float stretchX, float rescaleX, float width,
|
||||
float bitmapWidth, uint32_t& quadCount) {
|
||||
float previousStepX = 0.0f;
|
||||
|
||||
float x1 = 0.0f;
|
||||
float x2 = 0.0f;
|
||||
float u1 = 0.0f;
|
||||
|
||||
// Generate the row quad by quad
|
||||
for (uint32_t i = 0; i < xCount; i++) {
|
||||
float stepX = xDivs[i];
|
||||
const float segment = stepX - previousStepX;
|
||||
|
||||
if (i & 1) {
|
||||
x2 = x1 + floorf(segment * stretchX + 0.5f);
|
||||
} else {
|
||||
x2 = x1 + segment * rescaleX;
|
||||
}
|
||||
|
||||
float uOffset = x1 == x2 ? 0.0f : 0.5 - (0.5 * segment / (x2 - x1));
|
||||
float u2 = std::max(0.0f, stepX - uOffset) / bitmapWidth;
|
||||
u1 += uOffset / bitmapWidth;
|
||||
|
||||
if (stepX > 0.0f) {
|
||||
generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
|
||||
}
|
||||
|
||||
x1 = x2;
|
||||
u1 = stepX / bitmapWidth;
|
||||
|
||||
previousStepX = stepX;
|
||||
}
|
||||
|
||||
if (previousStepX != bitmapWidth) {
|
||||
x2 = width;
|
||||
generateQuad(vertex, x1, y1, x2, y2, u1, v1, 1.0f, v2, quadCount);
|
||||
}
|
||||
}
|
||||
|
||||
void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, float u1,
|
||||
float v1, float u2, float v2, uint32_t& quadCount) {
|
||||
const uint32_t oldQuadCount = quadCount;
|
||||
quadCount++;
|
||||
|
||||
x1 = std::max(x1, 0.0f);
|
||||
x2 = std::max(x2, 0.0f);
|
||||
y1 = std::max(y1, 0.0f);
|
||||
y2 = std::max(y2, 0.0f);
|
||||
|
||||
// Skip degenerate and transparent (empty) quads
|
||||
if ((mColors[oldQuadCount] == 0) || x1 >= x2 || y1 >= y2) {
|
||||
#if DEBUG_PATCHES_EMPTY_VERTICES
|
||||
PATCH_LOGD(" quad %d (empty)", oldQuadCount);
|
||||
PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.8f, %.8f", x1, y1, u1, v1);
|
||||
PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.8f, %.8f", x2, y2, u2, v2);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Record all non empty quads
|
||||
if (hasEmptyQuads) {
|
||||
quads.emplace_back(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
mUvMapper.map(u1, v1, u2, v2);
|
||||
|
||||
TextureVertex::set(vertex++, x1, y1, u1, v1);
|
||||
TextureVertex::set(vertex++, x2, y1, u2, v1);
|
||||
TextureVertex::set(vertex++, x1, y2, u1, v2);
|
||||
TextureVertex::set(vertex++, x2, y2, u2, v2);
|
||||
|
||||
verticesCount += 4;
|
||||
indexCount += 6;
|
||||
|
||||
#if DEBUG_PATCHES_VERTICES
|
||||
PATCH_LOGD(" quad %d", oldQuadCount);
|
||||
PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.8f, %.8f", x1, y1, u1, v1);
|
||||
PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.8f, %.8f", x2, y2, u2, v2);
|
||||
#endif
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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_PATCH_H
|
||||
#define ANDROID_HWUI_PATCH_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <androidfw/ResourceTypes.h>
|
||||
|
||||
#include "Rect.h"
|
||||
#include "UvMapper.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
struct TextureVertex;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 9-patch structures
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Patch {
|
||||
public:
|
||||
Patch(const float bitmapWidth, const float bitmapHeight, float width, float height,
|
||||
const UvMapper& mapper, const Res_png_9patch* patch);
|
||||
|
||||
/**
|
||||
* Returns the size of this patch's mesh in bytes.
|
||||
*/
|
||||
uint32_t getSize() const;
|
||||
|
||||
std::unique_ptr<TextureVertex[]> vertices;
|
||||
uint32_t verticesCount = 0;
|
||||
uint32_t indexCount = 0;
|
||||
bool hasEmptyQuads = false;
|
||||
std::vector<Rect> quads;
|
||||
|
||||
GLintptr positionOffset = 0;
|
||||
GLintptr textureOffset = 0;
|
||||
|
||||
private:
|
||||
void generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex, float y1,
|
||||
float y2, float v1, float v2, float stretchX, float rescaleX, float width,
|
||||
float bitmapWidth, uint32_t& quadCount);
|
||||
void generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, float u1,
|
||||
float v1, float u2, float v2, uint32_t& quadCount);
|
||||
|
||||
const uint32_t* mColors;
|
||||
UvMapper mUvMapper;
|
||||
}; // struct Patch
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_HWUI_PATCH_H
|
||||
@@ -1,481 +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 "GlLayer.h"
|
||||
#include "Matrix.h"
|
||||
#include "Rect.h"
|
||||
#include "RenderNode.h"
|
||||
#include "Vector.h"
|
||||
#include "utils/LinearAllocator.h"
|
||||
#include "utils/PaintUtils.h"
|
||||
|
||||
#include <androidfw/ResourceTypes.h>
|
||||
|
||||
class SkBitmap;
|
||||
class SkPaint;
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
struct ClipBase;
|
||||
class OffscreenBuffer;
|
||||
class RenderNode;
|
||||
class DeferredLayerUpdater;
|
||||
typedef uint16_t glyph_t;
|
||||
|
||||
struct Vertex;
|
||||
|
||||
namespace VectorDrawable {
|
||||
class Tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authoritative op list, used for generating the op ID enum, ID based LUTS, and
|
||||
* the functions to which they dispatch. Parameter macros are executed for each op,
|
||||
* in order, based on the op's type.
|
||||
*
|
||||
* There are 4 types of op, which defines dispatch/LUT capability:
|
||||
*
|
||||
* | DisplayList | Render | Merge |
|
||||
* -------------|-------------|-------------|-------------|
|
||||
* PRE RENDER | Yes | | |
|
||||
* RENDER ONLY | | Yes | |
|
||||
* UNMERGEABLE | Yes | Yes | |
|
||||
* MERGEABLE | Yes | Yes | Yes |
|
||||
*
|
||||
* PRE RENDER - These ops are recorded into DisplayLists, but can't be directly rendered. This
|
||||
* may be because they need to be transformed into other op types (e.g. CirclePropsOp),
|
||||
* be traversed to access multiple renderable ops within (e.g. RenderNodeOp), or because they
|
||||
* modify renderbuffer lifecycle, instead of directly rendering content (the various LayerOps).
|
||||
*
|
||||
* RENDER ONLY - These ops cannot be recorded into DisplayLists, and are instead implicitly
|
||||
* constructed from other commands/RenderNode properties. They cannot be merged.
|
||||
*
|
||||
* UNMERGEABLE - These ops can be recorded into DisplayLists and rendered directly, but do not
|
||||
* support merged rendering.
|
||||
*
|
||||
* MERGEABLE - These ops can be recorded into DisplayLists and rendered individually, or merged
|
||||
* under certain circumstances.
|
||||
*/
|
||||
#define MAP_OPS_BASED_ON_TYPE(PRE_RENDER_OP_FN, RENDER_ONLY_OP_FN, UNMERGEABLE_OP_FN, \
|
||||
MERGEABLE_OP_FN) \
|
||||
PRE_RENDER_OP_FN(RenderNodeOp) \
|
||||
PRE_RENDER_OP_FN(CirclePropsOp) \
|
||||
PRE_RENDER_OP_FN(RoundRectPropsOp) \
|
||||
PRE_RENDER_OP_FN(BeginLayerOp) \
|
||||
PRE_RENDER_OP_FN(EndLayerOp) \
|
||||
PRE_RENDER_OP_FN(BeginUnclippedLayerOp) \
|
||||
PRE_RENDER_OP_FN(EndUnclippedLayerOp) \
|
||||
PRE_RENDER_OP_FN(VectorDrawableOp) \
|
||||
\
|
||||
RENDER_ONLY_OP_FN(LayerOp) \
|
||||
RENDER_ONLY_OP_FN(CopyToLayerOp) \
|
||||
RENDER_ONLY_OP_FN(CopyFromLayerOp) \
|
||||
\
|
||||
UNMERGEABLE_OP_FN(ArcOp) \
|
||||
UNMERGEABLE_OP_FN(BitmapMeshOp) \
|
||||
UNMERGEABLE_OP_FN(BitmapRectOp) \
|
||||
UNMERGEABLE_OP_FN(ColorOp) \
|
||||
UNMERGEABLE_OP_FN(FunctorOp) \
|
||||
UNMERGEABLE_OP_FN(LinesOp) \
|
||||
UNMERGEABLE_OP_FN(OvalOp) \
|
||||
UNMERGEABLE_OP_FN(PathOp) \
|
||||
UNMERGEABLE_OP_FN(PointsOp) \
|
||||
UNMERGEABLE_OP_FN(RectOp) \
|
||||
UNMERGEABLE_OP_FN(RoundRectOp) \
|
||||
UNMERGEABLE_OP_FN(SimpleRectsOp) \
|
||||
UNMERGEABLE_OP_FN(TextOnPathOp) \
|
||||
UNMERGEABLE_OP_FN(TextureLayerOp) \
|
||||
\
|
||||
MERGEABLE_OP_FN(BitmapOp) \
|
||||
MERGEABLE_OP_FN(PatchOp) \
|
||||
MERGEABLE_OP_FN(TextOp)
|
||||
|
||||
/**
|
||||
* LUT generators, which will insert nullptr for unsupported ops
|
||||
*/
|
||||
#define NULLPTR_OP_FN(Type) nullptr,
|
||||
|
||||
#define BUILD_DEFERRABLE_OP_LUT(OP_FN) \
|
||||
{ MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) }
|
||||
|
||||
#define BUILD_MERGEABLE_OP_LUT(OP_FN) \
|
||||
{ MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) }
|
||||
|
||||
#define BUILD_RENDERABLE_OP_LUT(OP_FN) \
|
||||
{ MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) }
|
||||
|
||||
#define BUILD_FULL_OP_LUT(OP_FN) \
|
||||
{ MAP_OPS_BASED_ON_TYPE(OP_FN, OP_FN, OP_FN, OP_FN) }
|
||||
|
||||
/**
|
||||
* Op mapping functions, which skip unsupported ops.
|
||||
*
|
||||
* Note: Do not use for LUTS, since these do not preserve ID order.
|
||||
*/
|
||||
#define NULL_OP_FN(Type)
|
||||
|
||||
#define MAP_DEFERRABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN)
|
||||
|
||||
#define MAP_MERGEABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN)
|
||||
|
||||
#define MAP_RENDERABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN)
|
||||
|
||||
// Generate OpId enum
|
||||
#define IDENTITY_FN(Type) Type,
|
||||
namespace RecordedOpId {
|
||||
enum {
|
||||
MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN) Count,
|
||||
};
|
||||
}
|
||||
static_assert(RecordedOpId::RenderNodeOp == 0, "First index must be zero for LUTs to work");
|
||||
|
||||
#define BASE_PARAMS \
|
||||
const Rect &unmappedBounds, const Matrix4 &localMatrix, const ClipBase *localClip, \
|
||||
const SkPaint *paint
|
||||
#define BASE_PARAMS_PAINTLESS \
|
||||
const Rect &unmappedBounds, const Matrix4 &localMatrix, const ClipBase *localClip
|
||||
#define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, paint)
|
||||
#define SUPER_PAINTLESS(Type) \
|
||||
RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, nullptr)
|
||||
|
||||
struct RecordedOp {
|
||||
/* ID from RecordedOpId - generally used for jumping into function tables */
|
||||
const int opId;
|
||||
|
||||
/* bounds in *local* space, without accounting for DisplayList transformation, or stroke */
|
||||
const Rect unmappedBounds;
|
||||
|
||||
/* transform in recording space (vs DisplayList origin) */
|
||||
const Matrix4 localMatrix;
|
||||
|
||||
/* clip in recording space - nullptr if not clipped */
|
||||
const ClipBase* localClip;
|
||||
|
||||
/* optional paint, stored in base object to simplify merging logic */
|
||||
const SkPaint* paint;
|
||||
|
||||
protected:
|
||||
RecordedOp(unsigned int opId, BASE_PARAMS)
|
||||
: opId(opId)
|
||||
, unmappedBounds(unmappedBounds)
|
||||
, localMatrix(localMatrix)
|
||||
, localClip(localClip)
|
||||
, paint(paint) {}
|
||||
};
|
||||
|
||||
struct RenderNodeOp : RecordedOp {
|
||||
RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
|
||||
: SUPER_PAINTLESS(RenderNodeOp), renderNode(renderNode) {}
|
||||
RenderNode* renderNode; // not const, since drawing modifies it
|
||||
|
||||
/**
|
||||
* Holds the transformation between the projection surface ViewGroup and this RenderNode
|
||||
* drawing instance. Represents any translations / transformations done within the drawing of
|
||||
* the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
|
||||
* DisplayList draw instance.
|
||||
*
|
||||
* Note: doesn't include transformation within the RenderNode, or its properties.
|
||||
*/
|
||||
Matrix4 transformFromCompositingAncestor;
|
||||
bool skipInOrderDraw = false;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Standard Ops
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ArcOp : RecordedOp {
|
||||
ArcOp(BASE_PARAMS, float startAngle, float sweepAngle, bool useCenter)
|
||||
: SUPER(ArcOp), startAngle(startAngle), sweepAngle(sweepAngle), useCenter(useCenter) {}
|
||||
const float startAngle;
|
||||
const float sweepAngle;
|
||||
const bool useCenter;
|
||||
};
|
||||
|
||||
struct BitmapOp : RecordedOp {
|
||||
BitmapOp(BASE_PARAMS, Bitmap* bitmap) : SUPER(BitmapOp), bitmap(bitmap) {}
|
||||
Bitmap* bitmap;
|
||||
};
|
||||
|
||||
struct BitmapMeshOp : RecordedOp {
|
||||
BitmapMeshOp(BASE_PARAMS, Bitmap* bitmap, int meshWidth, int meshHeight, const float* vertices,
|
||||
const int* colors)
|
||||
: SUPER(BitmapMeshOp)
|
||||
, bitmap(bitmap)
|
||||
, meshWidth(meshWidth)
|
||||
, meshHeight(meshHeight)
|
||||
, vertices(vertices)
|
||||
, colors(colors) {}
|
||||
Bitmap* bitmap;
|
||||
const int meshWidth;
|
||||
const int meshHeight;
|
||||
const float* vertices;
|
||||
const int* colors;
|
||||
};
|
||||
|
||||
struct BitmapRectOp : RecordedOp {
|
||||
BitmapRectOp(BASE_PARAMS, Bitmap* bitmap, const Rect& src)
|
||||
: SUPER(BitmapRectOp), bitmap(bitmap), src(src) {}
|
||||
Bitmap* bitmap;
|
||||
const Rect src;
|
||||
};
|
||||
|
||||
struct CirclePropsOp : RecordedOp {
|
||||
CirclePropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
|
||||
float* x, float* y, float* radius)
|
||||
: RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClip, paint)
|
||||
, x(x)
|
||||
, y(y)
|
||||
, radius(radius) {}
|
||||
const float* x;
|
||||
const float* y;
|
||||
const float* radius;
|
||||
};
|
||||
|
||||
struct ColorOp : RecordedOp {
|
||||
// Note: unbounded op that will fillclip, so no bounds/matrix needed
|
||||
ColorOp(const ClipBase* localClip, int color, SkBlendMode mode)
|
||||
: RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
|
||||
, color(color)
|
||||
, mode(mode) {}
|
||||
const int color;
|
||||
const SkBlendMode mode;
|
||||
};
|
||||
|
||||
struct FunctorOp : RecordedOp {
|
||||
// Note: undefined record-time bounds, since this op fills the clip
|
||||
// TODO: explicitly define bounds
|
||||
FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor)
|
||||
: RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr)
|
||||
, functor(functor) {}
|
||||
Functor* functor;
|
||||
};
|
||||
|
||||
struct LinesOp : RecordedOp {
|
||||
LinesOp(BASE_PARAMS, const float* points, const int floatCount)
|
||||
: SUPER(LinesOp), points(points), floatCount(floatCount) {}
|
||||
const float* points;
|
||||
const int floatCount;
|
||||
};
|
||||
|
||||
struct OvalOp : RecordedOp {
|
||||
OvalOp(BASE_PARAMS) : SUPER(OvalOp) {}
|
||||
};
|
||||
|
||||
struct PatchOp : RecordedOp {
|
||||
PatchOp(BASE_PARAMS, Bitmap* bitmap, const Res_png_9patch* patch)
|
||||
: SUPER(PatchOp), bitmap(bitmap), patch(patch) {}
|
||||
Bitmap* bitmap;
|
||||
const Res_png_9patch* patch;
|
||||
};
|
||||
|
||||
struct PathOp : RecordedOp {
|
||||
PathOp(BASE_PARAMS, const SkPath* path) : SUPER(PathOp), path(path) {}
|
||||
const SkPath* path;
|
||||
};
|
||||
|
||||
struct PointsOp : RecordedOp {
|
||||
PointsOp(BASE_PARAMS, const float* points, const int floatCount)
|
||||
: SUPER(PointsOp), points(points), floatCount(floatCount) {}
|
||||
const float* points;
|
||||
const int floatCount;
|
||||
};
|
||||
|
||||
struct RectOp : RecordedOp {
|
||||
RectOp(BASE_PARAMS) : SUPER(RectOp) {}
|
||||
};
|
||||
|
||||
struct RoundRectOp : RecordedOp {
|
||||
RoundRectOp(BASE_PARAMS, float rx, float ry) : SUPER(RoundRectOp), rx(rx), ry(ry) {}
|
||||
const float rx;
|
||||
const float ry;
|
||||
};
|
||||
|
||||
struct RoundRectPropsOp : RecordedOp {
|
||||
RoundRectPropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
|
||||
float* left, float* top, float* right, float* bottom, float* rx, float* ry)
|
||||
: RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClip, paint)
|
||||
, left(left)
|
||||
, top(top)
|
||||
, right(right)
|
||||
, bottom(bottom)
|
||||
, rx(rx)
|
||||
, ry(ry) {}
|
||||
const float* left;
|
||||
const float* top;
|
||||
const float* right;
|
||||
const float* bottom;
|
||||
const float* rx;
|
||||
const float* ry;
|
||||
};
|
||||
|
||||
struct VectorDrawableOp : RecordedOp {
|
||||
VectorDrawableOp(VectorDrawable::Tree* tree, BASE_PARAMS_PAINTLESS)
|
||||
: SUPER_PAINTLESS(VectorDrawableOp), vectorDrawable(tree) {}
|
||||
VectorDrawable::Tree* vectorDrawable;
|
||||
};
|
||||
|
||||
struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?)
|
||||
SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
|
||||
: SUPER(SimpleRectsOp), vertices(vertices), vertexCount(vertexCount) {}
|
||||
Vertex* vertices;
|
||||
const size_t vertexCount;
|
||||
};
|
||||
|
||||
struct TextOp : RecordedOp {
|
||||
TextOp(BASE_PARAMS, const glyph_t* glyphs, const float* positions, int glyphCount, float x,
|
||||
float y)
|
||||
: SUPER(TextOp)
|
||||
, glyphs(glyphs)
|
||||
, positions(positions)
|
||||
, glyphCount(glyphCount)
|
||||
, x(x)
|
||||
, y(y) {}
|
||||
const glyph_t* glyphs;
|
||||
const float* positions;
|
||||
const int glyphCount;
|
||||
const float x;
|
||||
const float y;
|
||||
};
|
||||
|
||||
struct TextOnPathOp : RecordedOp {
|
||||
// TODO: explicitly define bounds
|
||||
TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
|
||||
const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset,
|
||||
float vOffset)
|
||||
: RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint)
|
||||
, glyphs(glyphs)
|
||||
, glyphCount(glyphCount)
|
||||
, path(path)
|
||||
, hOffset(hOffset)
|
||||
, vOffset(vOffset) {}
|
||||
const glyph_t* glyphs;
|
||||
const int glyphCount;
|
||||
|
||||
const SkPath* path;
|
||||
const float hOffset;
|
||||
const float vOffset;
|
||||
};
|
||||
|
||||
struct TextureLayerOp : RecordedOp {
|
||||
TextureLayerOp(BASE_PARAMS_PAINTLESS, DeferredLayerUpdater* layer)
|
||||
: SUPER_PAINTLESS(TextureLayerOp), layerHandle(layer) {}
|
||||
|
||||
// Copy an existing TextureLayerOp, replacing the underlying matrix
|
||||
TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix)
|
||||
: RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix,
|
||||
op.localClip, op.paint)
|
||||
, layerHandle(op.layerHandle) {}
|
||||
DeferredLayerUpdater* layerHandle;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Layers
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Stateful operation! denotes the creation of an off-screen layer,
|
||||
* and that commands following will render into it.
|
||||
*/
|
||||
struct BeginLayerOp : RecordedOp {
|
||||
BeginLayerOp(BASE_PARAMS) : SUPER(BeginLayerOp) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stateful operation! Denotes end of off-screen layer, and that
|
||||
* commands since last BeginLayerOp should be drawn into parent FBO.
|
||||
*
|
||||
* State in this op is empty, it just serves to signal that a layer has been finished.
|
||||
*/
|
||||
struct EndLayerOp : RecordedOp {
|
||||
EndLayerOp()
|
||||
: RecordedOp(RecordedOpId::EndLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {}
|
||||
};
|
||||
|
||||
struct BeginUnclippedLayerOp : RecordedOp {
|
||||
BeginUnclippedLayerOp(BASE_PARAMS) : SUPER(BeginUnclippedLayerOp) {}
|
||||
};
|
||||
|
||||
struct EndUnclippedLayerOp : RecordedOp {
|
||||
EndUnclippedLayerOp()
|
||||
: RecordedOp(RecordedOpId::EndUnclippedLayerOp, Rect(), Matrix4::identity(), nullptr,
|
||||
nullptr) {}
|
||||
};
|
||||
|
||||
struct CopyToLayerOp : RecordedOp {
|
||||
CopyToLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
|
||||
: RecordedOp(RecordedOpId::CopyToLayerOp, op.unmappedBounds, op.localMatrix,
|
||||
nullptr, // clip intentionally ignored
|
||||
op.paint)
|
||||
, layerHandle(layerHandle) {}
|
||||
|
||||
// Records a handle to the Layer object, since the Layer itself won't be
|
||||
// constructed until after this operation is constructed.
|
||||
OffscreenBuffer** layerHandle;
|
||||
};
|
||||
|
||||
// draw the parameter layer underneath
|
||||
struct CopyFromLayerOp : RecordedOp {
|
||||
CopyFromLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
|
||||
: RecordedOp(RecordedOpId::CopyFromLayerOp, op.unmappedBounds, op.localMatrix,
|
||||
nullptr, // clip intentionally ignored
|
||||
op.paint)
|
||||
, layerHandle(layerHandle) {}
|
||||
|
||||
// Records a handle to the Layer object, since the Layer itself won't be
|
||||
// constructed until after this operation is constructed.
|
||||
OffscreenBuffer** layerHandle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws an OffscreenBuffer.
|
||||
*
|
||||
* Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated,
|
||||
* when creating/tracking a SkPaint* during defer isn't worth the bother.
|
||||
*/
|
||||
struct LayerOp : RecordedOp {
|
||||
// Records a one-use (saveLayer) layer for drawing.
|
||||
LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle)
|
||||
: SUPER_PAINTLESS(LayerOp)
|
||||
, layerHandle(layerHandle)
|
||||
, alpha(paint ? paint->getAlpha() / 255.0f : 1.0f)
|
||||
, mode(PaintUtils::getBlendModeDirect(paint))
|
||||
, colorFilter(paint ? paint->getColorFilter() : nullptr) {}
|
||||
|
||||
explicit LayerOp(RenderNode& node)
|
||||
: RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()),
|
||||
Matrix4::identity(), nullptr, nullptr)
|
||||
, layerHandle(node.getLayerHandle())
|
||||
, alpha(node.properties().layerProperties().alpha() / 255.0f)
|
||||
, mode(node.properties().layerProperties().xferMode())
|
||||
, colorFilter(node.properties().layerProperties().colorFilter()) {}
|
||||
|
||||
// Records a handle to the Layer object, since the Layer itself won't be
|
||||
// constructed until after this operation is constructed.
|
||||
OffscreenBuffer** layerHandle;
|
||||
const float alpha;
|
||||
const SkBlendMode mode;
|
||||
|
||||
// pointer to object owned by either LayerProperties, or a recorded Paint object in a
|
||||
// BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used.
|
||||
SkColorFilter* colorFilter;
|
||||
};
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "DamageAccumulator.h"
|
||||
#include "Debug.h"
|
||||
#include "RecordedOp.h"
|
||||
#include "TreeInfo.h"
|
||||
#include "VectorDrawable.h"
|
||||
#include "renderstate/RenderState.h"
|
||||
|
||||
@@ -74,46 +74,6 @@ struct TextureVertex {
|
||||
|
||||
REQUIRE_COMPATIBLE_LAYOUT(TextureVertex);
|
||||
|
||||
/**
|
||||
* Simple structure to describe a vertex with a position, texture UV and an
|
||||
* sRGB color with alpha. The color is stored pre-multiplied in linear space.
|
||||
*/
|
||||
struct ColorTextureVertex {
|
||||
float x, y;
|
||||
float u, v;
|
||||
float r, g, b, a; // pre-multiplied linear
|
||||
|
||||
static inline void set(ColorTextureVertex* vertex, float x, float y, float u, float v,
|
||||
uint32_t color) {
|
||||
FloatColor c;
|
||||
c.set(color);
|
||||
*vertex = {x, y, u, v, c.r, c.g, c.b, c.a};
|
||||
}
|
||||
}; // struct ColorTextureVertex
|
||||
|
||||
REQUIRE_COMPATIBLE_LAYOUT(ColorTextureVertex);
|
||||
|
||||
/**
|
||||
* Simple structure to describe a vertex with a position and an alpha value.
|
||||
*/
|
||||
struct AlphaVertex {
|
||||
float x, y;
|
||||
float alpha;
|
||||
|
||||
static inline void set(AlphaVertex* vertex, float x, float y, float alpha) {
|
||||
*vertex = {x, y, alpha};
|
||||
}
|
||||
|
||||
static inline void copyWithOffset(AlphaVertex* vertex, const AlphaVertex& src, float x,
|
||||
float y) {
|
||||
AlphaVertex::set(vertex, src.x + x, src.y + y, src.alpha);
|
||||
}
|
||||
|
||||
static inline void setColor(AlphaVertex* vertex, float alpha) { vertex[0].alpha = alpha; }
|
||||
}; // struct AlphaVertex
|
||||
|
||||
REQUIRE_COMPATIBLE_LAYOUT(AlphaVertex);
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <DeviceInfo.h>
|
||||
#include <DisplayList.h>
|
||||
#include <GlLayer.h>
|
||||
#include <Matrix.h>
|
||||
#include <Properties.h>
|
||||
#include <Rect.h>
|
||||
@@ -28,8 +29,6 @@
|
||||
#include <renderstate/RenderState.h>
|
||||
#include <renderthread/RenderThread.h>
|
||||
|
||||
#include <RecordedOp.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -1,43 +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 <gtest/gtest.h>
|
||||
|
||||
#include "OpDumper.h"
|
||||
#include "tests/common/TestUtils.h"
|
||||
|
||||
using namespace android;
|
||||
using namespace android::uirenderer;
|
||||
|
||||
TEST(OpDumper, dump) {
|
||||
SkPaint paint;
|
||||
RectOp op(uirenderer::Rect(100, 100), Matrix4::identity(), nullptr, &paint);
|
||||
|
||||
std::stringstream stream;
|
||||
OpDumper::dump(op, stream);
|
||||
EXPECT_STREQ("RectOp [100 x 100]", stream.str().c_str());
|
||||
|
||||
stream.str("");
|
||||
OpDumper::dump(op, stream, 2);
|
||||
EXPECT_STREQ(" RectOp [100 x 100]", stream.str().c_str());
|
||||
|
||||
ClipRect clipRect(uirenderer::Rect(50, 50));
|
||||
op.localClip = &clipRect;
|
||||
|
||||
stream.str("");
|
||||
OpDumper::dump(op, stream, 2);
|
||||
EXPECT_STREQ(" RectOp [100 x 100] clip=[50 x 50] mode=0", stream.str().c_str());
|
||||
}
|
||||
Reference in New Issue
Block a user