summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Caches.h3
-rw-r--r--libs/hwui/DisplayListRenderer.cpp280
-rw-r--r--libs/hwui/DisplayListRenderer.h29
-rw-r--r--libs/hwui/LayerRenderer.cpp4
-rw-r--r--libs/hwui/LayerRenderer.h2
-rw-r--r--libs/hwui/OpenGLDebugRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLDebugRenderer.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp104
-rw-r--r--libs/hwui/OpenGLRenderer.h17
-rw-r--r--libs/hwui/ShapeCache.cpp77
-rw-r--r--libs/hwui/ShapeCache.h140
-rw-r--r--libs/hwui/TextureCache.cpp2
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/math.rs140
-rw-r--r--libs/rs/rsContext.cpp27
-rw-r--r--libs/rs/rsLocklessFifo.cpp7
-rw-r--r--libs/rs/rsScriptC.cpp32
-rw-r--r--libs/rs/rsScriptC.h7
-rw-r--r--libs/rs/rsScriptC_Lib.cpp10
-rw-r--r--libs/rs/scriptc/rs_core.rsh2
19 files changed, 767 insertions, 122 deletions
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 24585d5a14e9..0a9335f23288 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -162,6 +162,9 @@ public:
PathCache pathCache;
RoundRectShapeCache roundRectShapeCache;
CircleShapeCache circleShapeCache;
+ OvalShapeCache ovalShapeCache;
+ RectShapeCache rectShapeCache;
+ ArcShapeCache arcShapeCache;
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
FboCache fboCache;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index df446f9284db..c2106d49f7e4 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -107,6 +107,8 @@ const char* DisplayList::OP_NAMES[] = {
"DrawRect",
"DrawRoundRect",
"DrawCircle",
+ "DrawOval",
+ "DrawArc",
"DrawPath",
"DrawLines",
"DrawText",
@@ -115,7 +117,8 @@ const char* DisplayList::OP_NAMES[] = {
"ResetColorFilter",
"SetupColorFilter",
"ResetShadow",
- "SetupShadow"
+ "SetupShadow",
+ "DrawGLFunction"
};
DisplayList::DisplayList(const DisplayListRenderer& recorder) {
@@ -210,7 +213,8 @@ void DisplayList::init() {
mPathHeap = NULL;
}
-void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
+bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
+ bool needsInvalidate = false;
TextContainer text;
mReader.rewind();
@@ -227,87 +231,165 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
int saveCount = renderer.getSaveCount() - 1;
while (!mReader.eof()) {
int op = mReader.readInt();
- DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
switch (op) {
+ case DrawGLFunction: {
+ Functor *functor = (Functor *) getInt();
+ DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
+ needsInvalidate |= renderer.callDrawGLFunction(functor);
+ }
+ break;
case AcquireContext: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.acquireContext();
}
break;
case ReleaseContext: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.releaseContext();
}
break;
case Save: {
- renderer.save(getInt());
+ int rendererNum = getInt();
+ DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
+ renderer.save(rendererNum);
}
break;
case Restore: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.restore();
}
break;
case RestoreToCount: {
- renderer.restoreToCount(saveCount + getInt());
+ int restoreCount = saveCount + getInt();
+ DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
+ renderer.restoreToCount(restoreCount);
}
break;
case SaveLayer: {
- renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
- getPaint(), getInt());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ SkPaint* paint = getPaint();
+ int flags = getInt();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
+ OP_NAMES[op], f1, f2, f3, f4, paint, flags);
+ renderer.saveLayer(f1, f2, f3, f4, paint, flags);
}
break;
case SaveLayerAlpha: {
- renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
- getInt(), getInt());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ int alpha = getInt();
+ int flags = getInt();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
+ OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
+ renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
}
break;
case Translate: {
- renderer.translate(getFloat(), getFloat());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
+ renderer.translate(f1, f2);
}
break;
case Rotate: {
- renderer.rotate(getFloat());
+ float rotation = getFloat();
+ DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
+ renderer.rotate(rotation);
}
break;
case Scale: {
- renderer.scale(getFloat(), getFloat());
+ float sx = getFloat();
+ float sy = getFloat();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
+ renderer.scale(sx, sy);
}
break;
case Skew: {
- renderer.skew(getFloat(), getFloat());
+ float sx = getFloat();
+ float sy = getFloat();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
+ renderer.skew(sx, sy);
}
break;
case SetMatrix: {
- renderer.setMatrix(getMatrix());
+ SkMatrix* matrix = getMatrix();
+ DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
+ renderer.setMatrix(matrix);
}
break;
case ConcatMatrix: {
- renderer.concatMatrix(getMatrix());
+ SkMatrix* matrix = getMatrix();
+ DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
+ renderer.concatMatrix(matrix);
}
break;
case ClipRect: {
- renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
- (SkRegion::Op) getInt());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ int regionOp = getInt();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
+ f1, f2, f3, f4, regionOp);
+ renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
}
break;
case DrawDisplayList: {
- renderer.drawDisplayList(getDisplayList(), level + 1);
+ DisplayList* displayList = getDisplayList();
+ DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
+ displayList, level + 1);
+ needsInvalidate |= renderer.drawDisplayList(displayList, level + 1);
}
break;
case DrawLayer: {
- renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint());
+ Layer* layer = (Layer*) getInt();
+ float x = getFloat();
+ float y = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
+ layer, x, y, paint);
+ renderer.drawLayer(layer, x, y, paint);
}
break;
case DrawBitmap: {
- renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
+ SkBitmap* bitmap = getBitmap();
+ float x = getFloat();
+ float y = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
+ bitmap, x, y, paint);
+ renderer.drawBitmap(bitmap, x, y, paint);
}
break;
case DrawBitmapMatrix: {
- renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
+ SkBitmap* bitmap = getBitmap();
+ SkMatrix* matrix = getMatrix();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
+ bitmap, matrix, paint);
+ renderer.drawBitmap(bitmap, matrix, paint);
}
break;
case DrawBitmapRect: {
- renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
- getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ SkBitmap* bitmap = getBitmap();
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ float f5 = getFloat();
+ float f6 = getFloat();
+ float f7 = getFloat();
+ float f8 = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
+ (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
+ renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
}
break;
case DrawBitmapMesh: {
@@ -321,8 +403,10 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
bool hasColors = getInt();
int* colors = hasColors ? getInts(colorsCount) : NULL;
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
}
+ break;
case DrawPatch: {
int32_t* xDivs = NULL;
int32_t* yDivs = NULL;
@@ -337,71 +421,148 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
yDivs = getInts(yDivsCount);
colors = getUInts(numColors);
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
}
break;
case DrawColor: {
- renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
+ int color = getInt();
+ int xferMode = getInt();
+ DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
+ renderer.drawColor(color, (SkXfermode::Mode) xferMode);
}
break;
case DrawRect: {
- renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
+ f1, f2, f3, f4, paint);
+ renderer.drawRect(f1, f2, f3, f4, paint);
}
break;
case DrawRoundRect: {
- renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
- getFloat(), getFloat(), getPaint());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ float f5 = getFloat();
+ float f6 = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
+ renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
}
break;
case DrawCircle: {
- renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
+ (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
+ renderer.drawCircle(f1, f2, f3, paint);
+ }
+ break;
+ case DrawOval: {
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
+ renderer.drawOval(f1, f2, f3, f4, paint);
+ }
+ break;
+ case DrawArc: {
+ float f1 = getFloat();
+ float f2 = getFloat();
+ float f3 = getFloat();
+ float f4 = getFloat();
+ float f5 = getFloat();
+ float f6 = getFloat();
+ int i1 = getInt();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
+ renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
}
break;
case DrawPath: {
- renderer.drawPath(getPath(), getPaint());
+ SkPath* path = getPath();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
+ renderer.drawPath(path, paint);
}
break;
case DrawLines: {
int count = 0;
float* points = getFloats(count);
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.drawLines(points, count, getPaint());
}
break;
case DrawText: {
getText(&text);
- renderer.drawText(text.text(), text.length(), getInt(),
- getFloat(), getFloat(), getPaint());
+ int count = getInt();
+ float x = getFloat();
+ float y = getFloat();
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, x, y, paint);
+ renderer.drawText(text.text(), text.length(), count, x, y, paint);
}
break;
case ResetShader: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.resetShader();
}
break;
case SetupShader: {
- renderer.setupShader(getShader());
+ SkiaShader* shader = getShader();
+ DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
+ renderer.setupShader(shader);
}
break;
case ResetColorFilter: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.resetColorFilter();
}
break;
case SetupColorFilter: {
- renderer.setupColorFilter(getColorFilter());
+ SkiaColorFilter *colorFilter = getColorFilter();
+ DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
+ renderer.setupColorFilter(colorFilter);
}
break;
case ResetShadow: {
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.resetShadow();
}
break;
case SetupShadow: {
- renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
- }
- break;
+ float radius = getFloat();
+ float dx = getFloat();
+ float dy = getFloat();
+ int color = getInt();
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
+ radius, dx, dy, color);
+ renderer.setupShadow(radius, dx, dy, color);
+ }
+ break;
+ default:
+ DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
+ (char*) indent, OP_NAMES[op]);
+ break;
}
}
- DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2);
+ DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
+ return needsInvalidate;
}
///////////////////////////////////////////////////////////////////////////////
@@ -468,19 +629,40 @@ void DisplayListRenderer::setViewport(int width, int height) {
mHeight = height;
}
-void DisplayListRenderer::prepare(bool opaque) {
+void DisplayListRenderer::prepareDirty(float left, float top,
+ float right, float bottom, bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSaveCount = 1;
mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
+ mRestoreSaveCount = -1;
+}
+
+void DisplayListRenderer::finish() {
+ insertRestoreToCount();
+ OpenGLRenderer::finish();
+}
+
+void DisplayListRenderer::interrupt() {
+
}
+void DisplayListRenderer::resume() {
+}
void DisplayListRenderer::acquireContext() {
+ // TODO: probably noop instead of calling super
addOp(DisplayList::AcquireContext);
OpenGLRenderer::acquireContext();
}
+bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
+ addOp(DisplayList::DrawGLFunction);
+ addInt((int) functor);
+ return false; // No invalidate needed at record-time
+}
+
void DisplayListRenderer::releaseContext() {
+ // TODO: probably noop instead of calling super
addOp(DisplayList::ReleaseContext);
OpenGLRenderer::releaseContext();
}
@@ -497,8 +679,7 @@ void DisplayListRenderer::restore() {
}
void DisplayListRenderer::restoreToCount(int saveCount) {
- addOp(DisplayList::RestoreToCount);
- addInt(saveCount);
+ mRestoreSaveCount = saveCount;
OpenGLRenderer::restoreToCount(saveCount);
}
@@ -564,9 +745,10 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}
-void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
+bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
addOp(DisplayList::DrawDisplayList);
addDisplayList(displayList);
+ return false;
}
void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
@@ -658,6 +840,22 @@ void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* pa
addPaint(paint);
}
+void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
+ SkPaint* paint) {
+ addOp(DisplayList::DrawOval);
+ addBounds(left, top, right, bottom);
+ addPaint(paint);
+}
+
+void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+ addOp(DisplayList::DrawArc);
+ addBounds(left, top, right, bottom);
+ addPoint(startAngle, sweepAngle);
+ addInt(useCenter ? 1 : 0);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
addOp(DisplayList::DrawPath);
addPath(path);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 7f9db8a46e62..bab5149b093a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,6 +28,7 @@
#include <SkTSearch.h>
#include "OpenGLRenderer.h"
+#include "utils/Functor.h"
namespace android {
namespace uirenderer {
@@ -113,6 +114,8 @@ public:
DrawRect,
DrawRoundRect,
DrawCircle,
+ DrawOval,
+ DrawArc,
DrawPath,
DrawLines,
DrawText,
@@ -122,13 +125,14 @@ public:
SetupColorFilter,
ResetShadow,
SetupShadow,
+ DrawGLFunction,
};
static const char* OP_NAMES[];
void initFromDisplayListRenderer(const DisplayListRenderer& recorder);
- void replay(OpenGLRenderer& renderer, uint32_t level = 0);
+ bool replay(OpenGLRenderer& renderer, uint32_t level = 0);
private:
void init();
@@ -237,11 +241,16 @@ public:
DisplayList* getDisplayList();
void setViewport(int width, int height);
- void prepare(bool opaque);
+ void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ void finish();
+ bool callDrawGLFunction(Functor *functor);
void acquireContext();
void releaseContext();
+ void interrupt();
+ void resume();
+
int save(int flags);
void restore();
void restoreToCount(int saveCount);
@@ -261,7 +270,7 @@ public:
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
+ bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
@@ -278,6 +287,9 @@ public:
void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint);
void drawCircle(float x, float y, float radius, SkPaint* paint);
+ void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+ void drawArc(float left, float top, float right, float bottom,
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
@@ -318,7 +330,16 @@ public:
}
private:
+ void insertRestoreToCount() {
+ if (mRestoreSaveCount >= 0) {
+ mWriter.writeInt(DisplayList::RestoreToCount);
+ addInt(mRestoreSaveCount);
+ mRestoreSaveCount = -1;
+ }
+ }
+
inline void addOp(DisplayList::Op drawOp) {
+ insertRestoreToCount();
mWriter.writeInt(drawOp);
}
@@ -461,6 +482,8 @@ private:
DisplayList *mDisplayList;
+ int mRestoreSaveCount;
+
friend class DisplayList;
}; // class DisplayListRenderer
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 1c89577207c6..36709dcf98c7 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -26,7 +26,7 @@ namespace uirenderer {
// Rendering
///////////////////////////////////////////////////////////////////////////////
-void LayerRenderer::prepare(bool opaque) {
+void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
#if RENDER_LAYERS_AS_REGIONS
@@ -35,7 +35,7 @@ void LayerRenderer::prepare(bool opaque) {
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
- OpenGLRenderer::prepare(opaque);
+ OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque);
}
void LayerRenderer::finish() {
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 1e398470a082..d2f565e4f307 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -46,7 +46,7 @@ public:
~LayerRenderer() {
}
- void prepare(bool opaque);
+ void prepareDirty(float left, float top, float right, float bottom, bool opaque);
void finish();
bool hasLayer();
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
index 29bcde8e6d28..58d6c26940c7 100644
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -48,10 +48,10 @@ int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bot
return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
}
-void OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
+bool OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
mPrimitivesCount++;
StopWatch w("drawDisplayList");
- OpenGLRenderer::drawDisplayList(displayList);
+ return OpenGLRenderer::drawDisplayList(displayList);
}
void OpenGLDebugRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index aefa7bfa65ba..76e6a2e90b0f 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -40,7 +40,7 @@ public:
int saveLayer(float left, float top, float right, float bottom,
SkPaint* p, int flags);
- void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
+ bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 92aa4bd7955c..9f491b3d31c1 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -136,6 +136,10 @@ void OpenGLRenderer::setViewport(int width, int height) {
}
void OpenGLRenderer::prepare(bool opaque) {
+ prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
+}
+
+void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
mCaches.clearGarbage();
mSnapshot = new Snapshot(mFirstSnapshot,
@@ -146,15 +150,14 @@ void OpenGLRenderer::prepare(bool opaque) {
glDisable(GL_DITHER);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
+ mSnapshot->setClip(left, top, right, bottom);
+
if (!opaque) {
- glDisable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(0, 0, mWidth, mHeight);
- mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
}
void OpenGLRenderer::finish() {
@@ -213,6 +216,13 @@ void OpenGLRenderer::releaseContext() {
resume();
}
+bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
+ interrupt();
+ status_t result = (*functor)();
+ resume();
+ return (result == 0) ? false : true;
+}
+
///////////////////////////////////////////////////////////////////////////////
// State management
///////////////////////////////////////////////////////////////////////////////
@@ -1031,12 +1041,13 @@ void OpenGLRenderer::finishDrawTexture() {
// Drawing
///////////////////////////////////////////////////////////////////////////////
-void OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
+bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList) {
- displayList->replay(*this, level);
+ return displayList->replay(*this, level);
}
+ return false;
}
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
@@ -1094,10 +1105,10 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
- // TODO: Support the colors array
const uint32_t count = meshWidth * meshHeight * 6;
- TextureVertex mesh[count];
+ // TODO: Support the colors array
+ TextureVertex mesh[count];
TextureVertex* vertex = mesh;
for (int32_t y = 0; y < meshHeight; y++) {
for (int32_t x = 0; x < meshWidth; x++) {
@@ -1202,8 +1213,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
#if RENDER_LAYERS_AS_REGIONS
// Mark the current layer dirty where we are going to draw the patch
- if ((mSnapshot->flags & Snapshot::kFlagFboTarget) &&
- mSnapshot->region && mesh->hasEmptyQuads) {
+ if (hasLayer() && mesh->hasEmptyQuads) {
const size_t count = mesh->quads.size();
for (size_t i = 0; i < count; i++) {
const Rect& bounds = mesh->quads.itemAt(i);
@@ -1360,39 +1370,72 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
+void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, SkPaint* paint) {
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float x = left + texture->left - texture->offset;
+ const float y = top + texture->top - texture->offset;
+
+ drawPathTexture(texture, x, y, paint);
+}
+
void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
-
const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
right - left, bottom - top, rx, ry, paint);
- if (!texture) return;
- const AutoTexture autoCleanup(texture);
+ drawShape(left, top, texture, paint);
+}
- const float x = left + texture->left - texture->offset;
- const float y = top + texture->top - texture->offset;
+void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
- drawPathTexture(texture, x, y, paint);
+ glActiveTexture(gTextureUnits[0]);
+ const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
+ drawShape(x - radius, y - radius, texture, paint);
}
-void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
+ const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint);
+ drawShape(left, top, texture, paint);
+}
- const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
- if (!texture) return;
- const AutoTexture autoCleanup(texture);
+void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
- const float left = (x - radius) + texture->left - texture->offset;
- const float top = (y - radius) + texture->top - texture->offset;
+ if (fabs(sweepAngle) >= 360.0f) {
+ drawOval(left, top, right, bottom, paint);
+ return;
+ }
- drawPathTexture(texture, left, top, paint);
+ glActiveTexture(gTextureUnits[0]);
+ const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
+ startAngle, sweepAngle, useCenter, paint);
+ drawShape(left, top, texture, paint);
+}
+
+void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
+ SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+ const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint);
+ drawShape(left, top, texture, paint);
}
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
+ if (p->getStyle() != SkPaint::kFill_Style) {
+ drawRectAsShape(left, top, right, bottom, p);
+ return;
+ }
+
if (quickReject(left, top, right, bottom)) {
return;
}
@@ -1566,18 +1609,18 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
layer->alpha = alpha;
layer->mode = mode;
-
#if RENDER_LAYERS_AS_REGIONS
if (!layer->region.isEmpty()) {
if (layer->region.isRect()) {
const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
composeLayerRect(layer, r);
} else if (layer->mesh) {
+ const float a = alpha / 255.0f;
const Rect& rect = layer->layer;
setupDraw();
setupDrawWithTexture();
- setupDrawColor(alpha, alpha, alpha, alpha);
+ setupDrawColor(a, a, a, a);
setupDrawColorFilter();
setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
setupDrawProgram();
@@ -1706,12 +1749,17 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float
if (underlineWidth > 0.0f) {
const float textSize = paint->getTextSize();
- const float strokeWidth = textSize * kStdUnderline_Thickness;
+ // TODO: Support stroke width < 1.0f when we have AA lines
+ const float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
const float left = x - offsetX;
float top = 0.0f;
- const int pointsCount = 4 * (flags & SkPaint::kStrikeThruText_Flag ? 2 : 1);
+ int linesCount = 0;
+ if (flags & SkPaint::kUnderlineText_Flag) linesCount++;
+ if (flags & SkPaint::kStrikeThruText_Flag) linesCount++;
+
+ const int pointsCount = 4 * linesCount;
float points[pointsCount];
int currentPoint = 0;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 42e93adfef22..77de1d2270a8 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -27,6 +27,7 @@
#include <SkShader.h>
#include <SkXfermode.h>
+#include <utils/Functor.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
@@ -61,13 +62,15 @@ public:
virtual void setViewport(int width, int height);
- virtual void prepare(bool opaque);
+ void prepare(bool opaque);
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
// These two calls must not be recorded in display lists
- void interrupt();
- void resume();
+ virtual void interrupt();
+ virtual void resume();
+ virtual bool callDrawGLFunction(Functor *functor);
virtual void acquireContext();
virtual void releaseContext();
@@ -95,7 +98,7 @@ public:
bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
+ virtual bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
@@ -112,6 +115,9 @@ public:
virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint);
virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
+ virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawArc(float left, float top, float right, float bottom,
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
@@ -277,6 +283,9 @@ private:
void drawColorRect(float left, float top, float right, float bottom,
int color, SkXfermode::Mode mode, bool ignoreTransform = false);
+ void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
+ void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
+
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
* are transformed by the current snapshot's transform matrix.
diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp
index b78eecba5215..0d7cd9cb9a72 100644
--- a/libs/hwui/ShapeCache.cpp
+++ b/libs/hwui/ShapeCache.cpp
@@ -68,5 +68,82 @@ PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
return texture;
}
+///////////////////////////////////////////////////////////////////////////////
+// Ovals
+///////////////////////////////////////////////////////////////////////////////
+
+OvalShapeCache::OvalShapeCache(): ShapeCache<OvalShapeCacheEntry>(
+ "oval", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* OvalShapeCache::getOval(float width, float height, SkPaint* paint) {
+ OvalShapeCacheEntry entry(width, height, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ SkRect r;
+ r.set(0.0f, 0.0f, width, height);
+ path.addOval(r, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Rects
+///////////////////////////////////////////////////////////////////////////////
+
+RectShapeCache::RectShapeCache(): ShapeCache<RectShapeCacheEntry>(
+ "rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) {
+ RectShapeCacheEntry entry(width, height, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ path.addRect(0.0f, 0.0f, width, height, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Arcs
+///////////////////////////////////////////////////////////////////////////////
+
+ArcShapeCache::ArcShapeCache(): ShapeCache<ArcShapeCacheEntry>(
+ "arc", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* ArcShapeCache::getArc(float width, float height,
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+ ArcShapeCacheEntry entry(width, height, startAngle, sweepAngle, useCenter, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ SkRect r;
+ r.set(0.0f, 0.0f, width, height);
+ if (useCenter) {
+ path.moveTo(r.centerX(), r.centerY());
+ }
+ path.arcTo(r, startAngle, sweepAngle, !useCenter);
+ if (useCenter) {
+ path.close();
+ }
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index c62793180838..e53546605f13 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -76,6 +76,7 @@ struct PathTexture: public Texture {
struct ShapeCacheEntry {
enum ShapeType {
kShapeNone,
+ kShapeRect,
kShapeRoundRect,
kShapeCircle,
kShapeOval,
@@ -216,6 +217,122 @@ private:
uint32_t mRadius;
}; // CircleShapeCacheEntry
+struct OvalShapeCacheEntry: public ShapeCacheEntry {
+ OvalShapeCacheEntry(float width, float height, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeOval, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ }
+
+ OvalShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = mHeight = 0;
+ }
+
+ OvalShapeCacheEntry(const OvalShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const OvalShapeCacheEntry& rhs = (const OvalShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+}; // OvalShapeCacheEntry
+
+struct RectShapeCacheEntry: public ShapeCacheEntry {
+ RectShapeCacheEntry(float width, float height, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeRect, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ }
+
+ RectShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = mHeight = 0;
+ }
+
+ RectShapeCacheEntry(const RectShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const RectShapeCacheEntry& rhs = (const RectShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+}; // RectShapeCacheEntry
+
+struct ArcShapeCacheEntry: public ShapeCacheEntry {
+ ArcShapeCacheEntry(float width, float height, float startAngle, float sweepAngle,
+ bool useCenter, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeArc, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ mStartAngle = *(uint32_t*) &startAngle;
+ mSweepAngle = *(uint32_t*) &sweepAngle;
+ mUseCenter = useCenter ? 1 : 0;
+ }
+
+ ArcShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = 0;
+ mHeight = 0;
+ mStartAngle = 0;
+ mSweepAngle = 0;
+ mUseCenter = 0;
+ }
+
+ ArcShapeCacheEntry(const ArcShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ mStartAngle = entry.mStartAngle;
+ mSweepAngle = entry.mSweepAngle;
+ mUseCenter = entry.mUseCenter;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const ArcShapeCacheEntry& rhs = (const ArcShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ LTE_INT(mStartAngle) {
+ LTE_INT(mSweepAngle) {
+ LTE_INT(mUseCenter) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mStartAngle;
+ uint32_t mSweepAngle;
+ uint32_t mUseCenter;
+}; // ArcShapeCacheEntry
+
/**
* A simple LRU shape cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
@@ -289,8 +406,29 @@ public:
CircleShapeCache();
PathTexture* getCircle(float radius, SkPaint* paint);
-}; // class RoundRectShapeCache
+}; // class CircleShapeCache
+
+class OvalShapeCache: public ShapeCache<OvalShapeCacheEntry> {
+public:
+ OvalShapeCache();
+
+ PathTexture* getOval(float width, float height, SkPaint* paint);
+}; // class OvalShapeCache
+
+class RectShapeCache: public ShapeCache<RectShapeCacheEntry> {
+public:
+ RectShapeCache();
+
+ PathTexture* getRect(float width, float height, SkPaint* paint);
+}; // class RectShapeCache
+
+class ArcShapeCache: public ShapeCache<ArcShapeCacheEntry> {
+public:
+ ArcShapeCache();
+ PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
+ bool useCenter, SkPaint* paint);
+}; // class ArcShapeCache
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 6fc2ddb6e2ca..e560b8f154f7 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -60,7 +60,7 @@ void TextureCache::init() {
mCache.setOnEntryRemovedListener(this);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
- LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
+ INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
mDebugEnabled = readDebugLevel() & kDebugCaches;
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
index 02993fe5bb05..8cad82bfd569 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -12,6 +12,31 @@ volatile int2 i2;
volatile int3 i3;
volatile int4 i4;
+volatile uint ui1;
+volatile uint2 ui2;
+volatile uint3 ui3;
+volatile uint4 ui4;
+
+volatile short s1;
+volatile short2 s2;
+volatile short3 s3;
+volatile short4 s4;
+
+volatile ushort us1;
+volatile ushort2 us2;
+volatile ushort3 us3;
+volatile ushort4 us4;
+
+volatile char c1;
+volatile char2 c2;
+volatile char3 c3;
+volatile char4 c4;
+
+volatile uchar uc1;
+volatile uchar2 uc2;
+volatile uchar3 uc3;
+volatile uchar4 uc4;
+
#define TEST_FN_FUNC_FN(fnc) \
rsDebug("Testing " #fnc, 0); \
f1 = fnc(f1); \
@@ -168,9 +193,124 @@ static bool test_fp_math(uint32_t index) {
return failed;
}
+#define DECL_INT(prefix) \
+volatile char prefix##_c_1 = 1; \
+volatile char2 prefix##_c_2 = 1; \
+volatile char3 prefix##_c_3 = 1; \
+volatile char4 prefix##_c_4 = 1; \
+volatile uchar prefix##_uc_1 = 1; \
+volatile uchar2 prefix##_uc_2 = 1; \
+volatile uchar3 prefix##_uc_3 = 1; \
+volatile uchar4 prefix##_uc_4 = 1; \
+volatile short prefix##_s_1 = 1; \
+volatile short2 prefix##_s_2 = 1; \
+volatile short3 prefix##_s_3 = 1; \
+volatile short4 prefix##_s_4 = 1; \
+volatile ushort prefix##_us_1 = 1; \
+volatile ushort2 prefix##_us_2 = 1; \
+volatile ushort3 prefix##_us_3 = 1; \
+volatile ushort4 prefix##_us_4 = 1; \
+volatile int prefix##_i_1 = 1; \
+volatile int2 prefix##_i_2 = 1; \
+volatile int3 prefix##_i_3 = 1; \
+volatile int4 prefix##_i_4 = 1; \
+volatile uint prefix##_ui_1 = 1; \
+volatile uint2 prefix##_ui_2 = 1; \
+volatile uint3 prefix##_ui_3 = 1; \
+volatile uint4 prefix##_ui_4 = 1; \
+volatile long prefix##_l_1 = 1; \
+volatile ulong prefix##_ul_1 = 1;
+
+#define TEST_INT_OP_TYPE(op, type) \
+rsDebug("Testing " #op " for " #type "1", i++); \
+res_##type##_1 = src1_##type##_1 op src2_##type##_1; \
+rsDebug("Testing " #op " for " #type "2", i++); \
+res_##type##_2 = src1_##type##_2 op src2_##type##_2; \
+rsDebug("Testing " #op " for " #type "3", i++); \
+res_##type##_3 = src1_##type##_3 op src2_##type##_3; \
+rsDebug("Testing " #op " for " #type "4", i++); \
+res_##type##_4 = src1_##type##_4 op src2_##type##_4;
+
+#define TEST_INT_OP(op) \
+TEST_INT_OP_TYPE(op, c) \
+TEST_INT_OP_TYPE(op, uc) \
+TEST_INT_OP_TYPE(op, s) \
+TEST_INT_OP_TYPE(op, us) \
+TEST_INT_OP_TYPE(op, i) \
+TEST_INT_OP_TYPE(op, ui) \
+rsDebug("Testing " #op " for l1", i++); \
+res_l_1 = src1_l_1 op src2_l_1; \
+rsDebug("Testing " #op " for ul1", i++); \
+res_ul_1 = src1_ul_1 op src2_ul_1;
+
+DECL_INT(res)
+DECL_INT(src1)
+DECL_INT(src2)
+
+static bool test_basic_operators() {
+ bool failed = false;
+ int i = 0;
+
+ TEST_INT_OP(+);
+ TEST_INT_OP(-);
+ TEST_INT_OP(*);
+ TEST_INT_OP(/);
+ TEST_INT_OP(%);
+ TEST_INT_OP(<<);
+ TEST_INT_OP(>>);
+
+ if (failed) {
+ rsDebug("test_basic_operators FAILED", 0);
+ }
+ else {
+ rsDebug("test_basic_operators PASSED", 0);
+ }
+
+ return failed;
+}
+
+#define TEST_CVT(to, from, type) \
+rsDebug("Testing convert from " #from " to " #to, 0); \
+to##1 = from##1; \
+to##2 = convert_##type##2(from##2); \
+to##3 = convert_##type##3(from##3); \
+to##4 = convert_##type##4(from##4);
+
+#define TEST_CVT_MATRIX(to, type) \
+TEST_CVT(to, c, type); \
+TEST_CVT(to, uc, type); \
+TEST_CVT(to, s, type); \
+TEST_CVT(to, us, type); \
+TEST_CVT(to, i, type); \
+TEST_CVT(to, ui, type); \
+TEST_CVT(to, f, type); \
+
+static bool test_convert() {
+ bool failed = false;
+
+ TEST_CVT_MATRIX(c, char);
+ TEST_CVT_MATRIX(uc, uchar);
+ TEST_CVT_MATRIX(s, short);
+ TEST_CVT_MATRIX(us, ushort);
+ TEST_CVT_MATRIX(i, int);
+ TEST_CVT_MATRIX(ui, uint);
+ TEST_CVT_MATRIX(f, float);
+
+ if (failed) {
+ rsDebug("test_convert FAILED", 0);
+ }
+ else {
+ rsDebug("test_convert PASSED", 0);
+ }
+
+ return failed;
+}
+
void math_test(uint32_t index, int test_num) {
bool failed = false;
+ failed |= test_convert();
failed |= test_fp_math(index);
+ failed |= test_basic_operators();
if (failed) {
rsSendToClientBlocking(RS_MSG_TEST_FAILED);
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 3acb62460de0..40cb5c746e47 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -201,9 +201,9 @@ bool Context::initGLThread() {
mGL.mExtensions = glGetString(GL_EXTENSIONS);
//LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
- LOGV("GL Version %s", mGL.mVersion);
+ //LOGV("GL Version %s", mGL.mVersion);
//LOGV("GL Vendor %s", mGL.mVendor);
- LOGV("GL Renderer %s", mGL.mRenderer);
+ //LOGV("GL Renderer %s", mGL.mRenderer);
//LOGV("GL Extensions %s", mGL.mExtensions);
const char *verptr = NULL;
@@ -468,7 +468,6 @@ void * Context::threadProc(void *vrsc) {
return NULL;
}
- rsc->mScriptC.init(rsc);
if (rsc->mIsGraphicsContext) {
rsc->mStateRaster.init(rsc);
rsc->setProgramRaster(NULL);
@@ -528,7 +527,7 @@ void * Context::threadProc(void *vrsc) {
}
void Context::destroyWorkerThreadResources() {
- LOGV("destroyWorkerThreadResources 1");
+ //LOGV("destroyWorkerThreadResources 1");
if (mIsGraphicsContext) {
mRaster.clear();
mFragment.clear();
@@ -544,7 +543,7 @@ void Context::destroyWorkerThreadResources() {
mShaderCache.cleanupAll();
}
ObjectBase::zeroAllUserRef(this);
- LOGV("destroyWorkerThreadResources 2");
+ //LOGV("destroyWorkerThreadResources 2");
mExit = true;
}
@@ -552,7 +551,7 @@ void * Context::helperThreadProc(void *vrsc) {
Context *rsc = static_cast<Context *>(vrsc);
uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount);
- LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+ //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
rsc->mWorkers.mLaunchSignals[idx].init();
rsc->mWorkers.mNativeThreadId[idx] = gettid();
@@ -573,7 +572,7 @@ void * Context::helperThreadProc(void *vrsc) {
LOGE("pthread_setspecific %i", status);
}
- while (rsc->mRunning) {
+ while (!rsc->mExit) {
rsc->mWorkers.mLaunchSignals[idx].wait();
if (rsc->mWorkers.mLaunchCallback) {
rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx);
@@ -582,7 +581,7 @@ void * Context::helperThreadProc(void *vrsc) {
rsc->mWorkers.mCompleteSignal.set();
}
- LOGV("RS helperThread exiting %p idx=%i", rsc, idx);
+ //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
return NULL;
}
@@ -730,6 +729,18 @@ Context::~Context() {
mIO.shutdown();
int status = pthread_join(mThreadId, &res);
+ // Cleanup compute threads.
+ mWorkers.mLaunchData = NULL;
+ mWorkers.mLaunchCallback = NULL;
+ mWorkers.mRunningCount = (int)mWorkers.mCount;
+ for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
+ mWorkers.mLaunchSignals[ct].set();
+ }
+ for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
+ int status = pthread_join(mWorkers.mThreadId[ct], &res);
+ }
+ rsAssert(!mWorkers.mRunningCount);
+
// Global structure cleanup.
pthread_mutex_lock(&gInitMutex);
if (mDev) {
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index eb2af1cda757..3f8854330acf 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -76,7 +76,8 @@ uint32_t LocklessCommandFifo::getFreeSpace() const {
}
bool LocklessCommandFifo::isEmpty() const {
- return mPut == mGet;
+ uint32_t p = android_atomic_acquire_load((int32_t *)&mPut);
+ return ((uint8_t *)p) == mGet;
}
@@ -155,7 +156,9 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) {
void LocklessCommandFifo::next() {
uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
- mGet += ((bytes + 3) & ~3) + 4;
+
+ android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet);
+ //mGet += ((bytes + 3) & ~3) + 4;
if (isEmpty()) {
mSignalToControl.set();
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index eecfa16b43a4..3858e1cfc0de 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -421,21 +421,9 @@ void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len
}
ScriptCState::ScriptCState() {
- mScript.clear();
}
ScriptCState::~ScriptCState() {
- mScript.clear();
-}
-
-void ScriptCState::init(Context *rsc) {
- clear(rsc);
-}
-
-void ScriptCState::clear(Context *rsc) {
- rsAssert(rsc);
- mScript.clear();
- mScript.set(new ScriptC(rsc));
}
static void* symbolLookup(void* pContext, char const* name) {
@@ -608,8 +596,6 @@ namespace android {
namespace renderscript {
void rsi_ScriptCBegin(Context * rsc) {
- ScriptCState *ss = &rsc->mScriptC;
- ss->clear(rsc);
}
void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) {
@@ -618,8 +604,8 @@ void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) {
char *t = (char *)malloc(len + 1);
memcpy(t, text, len);
t[len] = 0;
- ss->mScript->mEnviroment.mScriptText = t;
- ss->mScript->mEnviroment.mScriptTextLength = len;
+ ss->mScriptText = t;
+ ss->mScriptLen = len;
}
@@ -630,17 +616,19 @@ RsScript rsi_ScriptCCreate(Context *rsc,
{
ScriptCState *ss = &rsc->mScriptC;
- ObjectBaseRef<ScriptC> s(ss->mScript);
- ss->mScript.clear();
+ ScriptC *s = new ScriptC(rsc);
+ s->mEnviroment.mScriptText = ss->mScriptText;
+ s->mEnviroment.mScriptTextLength = ss->mScriptLen;
+ ss->mScriptText = NULL;
+ ss->mScriptLen = 0;
s->incUserRef();
- if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) {
+ if (!ss->runCompiler(rsc, s, resName, cacheDir)) {
// Error during compile, destroy s and return null.
- s->zeroUserRef();
+ delete s;
return NULL;
}
- ss->clear(rsc);
- return s.get();
+ return s;
}
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 612e38a3b5aa..7143c671a658 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -76,11 +76,9 @@ public:
ScriptCState();
~ScriptCState();
- ObjectBaseRef<ScriptC> mScript;
+ char * mScriptText;
+ size_t mScriptLen;
- void init(Context *rsc);
-
- void clear(Context *rsc);
bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
struct SymbolTable_t {
@@ -88,7 +86,6 @@ public:
void * mPtr;
bool threadable;
};
- //static SymbolTable_t gSyms[];
static const SymbolTable_t * lookupSymbol(const char *);
static const SymbolTable_t * lookupSymbolCL(const char *);
static const SymbolTable_t * lookupSymbolGL(const char *);
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index f550d9870b06..beb4d724e05e 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -305,6 +305,14 @@ int SC_modsi3(int a, int b) {
return a % b;
}
+unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
+ return a / b;
+}
+
+unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
+ return a % b;
+}
+
int SC_getAllocation(const void *ptr) {
GET_TLS();
const Allocation *alloc = sc->ptrToAllocation(ptr);
@@ -363,6 +371,8 @@ void SC_ForEach2(RsScript vs,
static ScriptCState::SymbolTable_t gSyms[] = {
{ "__divsi3", (void *)&SC_divsi3, true },
{ "__modsi3", (void *)&SC_modsi3, true },
+ { "__udivsi3", (void *)&SC_udivsi3, true },
+ { "__umodsi3", (void *)&SC_umodsi3, true },
// allocation
{ "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index f3e0ab04f819..21c0f7b6832a 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -683,7 +683,7 @@ _RS_STATIC void __attribute__((overloadable))
rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
- q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->z + q->w*rhs->y;
+ q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
}