diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/Caches.h | 3 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 280 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.h | 29 | ||||
| -rw-r--r-- | libs/hwui/LayerRenderer.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/LayerRenderer.h | 2 | ||||
| -rw-r--r-- | libs/hwui/OpenGLDebugRenderer.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/OpenGLDebugRenderer.h | 2 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 104 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 17 | ||||
| -rw-r--r-- | libs/hwui/ShapeCache.cpp | 77 | ||||
| -rw-r--r-- | libs/hwui/ShapeCache.h | 140 | ||||
| -rw-r--r-- | libs/hwui/TextureCache.cpp | 2 | ||||
| -rw-r--r-- | libs/rs/java/tests/src/com/android/rs/test/math.rs | 140 | ||||
| -rw-r--r-- | libs/rs/rsContext.cpp | 27 | ||||
| -rw-r--r-- | libs/rs/rsLocklessFifo.cpp | 7 | ||||
| -rw-r--r-- | libs/rs/rsScriptC.cpp | 32 | ||||
| -rw-r--r-- | libs/rs/rsScriptC.h | 7 | ||||
| -rw-r--r-- | libs/rs/rsScriptC_Lib.cpp | 10 | ||||
| -rw-r--r-- | libs/rs/scriptc/rs_core.rsh | 2 |
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; } |