static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong regionPtr, jlong paintPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); if (paint->getStyle() != Paint::kFill_Style || (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) { SkRegion::Iterator it(*region); while (!it.done()) { const SkIRect& r = it.rect(); renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); it.next(); } } else { int count = 0; Vector<float> rects; SkRegion::Iterator it(*region); while (!it.done()) { const SkIRect& r = it.rect(); rects.push(r.fLeft); rects.push(r.fTop); rects.push(r.fRight); rects.push(r.fBottom); count += 4; it.next(); } renderer->drawRects(rects.array(), count, paint); } }
static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint); }
static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong regionPtr, jint op) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op)); return result ? JNI_TRUE : JNI_FALSE; }
static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong pathPtr, jlong paintPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); SkPath* path = reinterpret_cast<SkPath*>(pathPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawPath(path, paint); }
static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz, jlong rendererPtr, jint alpha, jint saveFlags) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags); }
static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jlong paintPtr, jint saveFlags) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); }
static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong functorPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Functor* functor = reinterpret_cast<Functor*>(functorPtr); android::uirenderer::Rect dirty; return renderer->callDrawGLFunction(functor, dirty); }
static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jlong paintPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawOval(left, top, right, bottom, paint); }
static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, jlong rendererPtr, jintArray colors, jint offset, jint stride, jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) { // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will // correct the alphaType to kOpaque_SkAlphaType. const SkImageInfo info = SkImageInfo::Make(width, height, hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, kPremul_SkAlphaType); SkBitmap* bitmap = new SkBitmap; if (!bitmap->allocPixels(info)) { delete bitmap; return; } if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) { delete bitmap; return; } DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); // apply transform directly to canvas, so it affects shaders correctly renderer->save(SkCanvas::kMatrix_SaveFlag); renderer->translate(left, top); renderer->drawBitmapData(bitmap, paint); renderer->restore(); // Note - bitmap isn't deleted as DisplayListRenderer owns it now }
static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jint op) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); const bool result = renderer->clipRect(left, top, right, bottom, static_cast<SkRegion::Op>(op)); return result ? JNI_TRUE : JNI_FALSE; }
static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); jfloat* storage = env->GetFloatArrayElements(points, NULL); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawLines(storage + offset, count, paint); env->ReleaseFloatArrayElements(points, storage, 0); }
static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); renderer->drawCircle(xProp, yProp, radiusProp, paintProp); }
static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz, jlong rendererPtr, jobject rect) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); env->CallVoidMethod(rect, gRectClassInfo.set, int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE; }
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jlong patchPtr, float left, float top, float right, float bottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); }
static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint); }
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr, float left, float top, float right, float bottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); // This object allows the renderer to allocate a global JNI ref to the buffer object. JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); }
static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jfloat left, jfloat top, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); // apply transform directly to canvas, so it affects shaders correctly renderer->save(SkCanvas::kMatrix_SaveFlag); renderer->translate(left, top); renderer->drawBitmap(bitmap, paint); renderer->restore(); }
static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong renderNodePtr, jobject dirty, jint flags) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); android::uirenderer::Rect bounds; status_t status = renderer->drawRenderNode(renderNode, bounds, flags); if (status != DrawGlInfo::kStatusDone && dirty != NULL) { env->CallVoidMethod(dirty, gRectClassInfo.set, int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); } return status; }
static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); // This object allows the renderer to allocate a global JNI ref to the buffer object. JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint); }
static void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr); CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr); CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr); CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr); CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr); CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr); CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp); }
sp<RenderNode> createCard(int x, int y, int width, int height) { sp<RenderNode> node = new RenderNode(); node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height); node->mutateStagingProperties().setElevation(dp(16)); node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1); node->mutateStagingProperties().mutableOutline().setShouldClip(true); node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z); DisplayListRenderer* renderer = startRecording(node.get()); renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode); endRecording(renderer, node.get()); return node; }
static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint); if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0); if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0); }
static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jfloat left, jfloat top, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); // This object allows the renderer to allocate a global JNI ref to the buffer object. JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); // apply transform directly to canvas, so it affects shaders correctly renderer->save(SkCanvas::kMatrix_SaveFlag); renderer->translate(left, top); renderer->drawBitmap(bitmap, paint); renderer->restore(); }
static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz, jlong rendererPtr, jint clearBits, jint setBits) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); renderer->setupPaintFilter(clearBits, setBits); }
int main() { createTestEnvironment(); // create the native surface const int width = gDisplay.w; const int height = gDisplay.h; sp<SurfaceControl> control = createWindow(width, height); sp<Surface> surface = control->getSurface(); RenderNode* rootNode = new RenderNode(); rootNode->incStrong(0); rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height); rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); rootNode->mutateStagingProperties().setClipToBounds(false); rootNode->setPropertyFieldsDirty(RenderNode::GENERIC); ContextFactory factory; RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); proxy->loadSystemProperties(); proxy->initialize(surface); float lightX = width / 2.0; proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)}, dp(800.0f), 255 * 0.075, 255 * 0.15); android::uirenderer::Rect DUMMY; std::vector< sp<RenderNode> > cards; DisplayListRenderer* renderer = startRecording(rootNode); renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); renderer->insertReorderBarrier(true); for (int x = dp(16); x < (width - dp(116)); x += dp(116)) { for (int y = dp(16); y < (height - dp(116)); y += dp(116)) { sp<RenderNode> card = createCard(x, y, dp(100), dp(100)); renderer->drawRenderNode(card.get(), DUMMY, 0); cards.push_back(card); } } renderer->insertReorderBarrier(false); endRecording(renderer, rootNode); for (int i = 0; i < 150; i++) { ATRACE_NAME("UI-Draw Frame"); for (size_t ci = 0; ci < cards.size(); ci++) { cards[ci]->mutateStagingProperties().setTranslationX(i); cards[ci]->mutateStagingProperties().setTranslationY(i); cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); } nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density); usleep(12000); } sleep(5); delete proxy; rootNode->decStrong(0); printf("Success!\n"); return 0; }
static DisplayListRenderer* startRecording(RenderNode* node) { DisplayListRenderer* renderer = new DisplayListRenderer(); renderer->setViewport(node->getWidth(), node->getHeight()); renderer->prepare(false); return renderer; }
static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz, jlong rendererPtr, jint width, jint height) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); renderer->setViewport(width, height); }
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); renderer->drawLayer(layer, x, y); }
static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz, jlong rendererPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); renderer->resetPaintFilter(); }
static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env, jobject clazz, jlong rendererPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); return reinterpret_cast<jlong>(renderer->finishRecording()); }