/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can
 * be found in the LICENSE file.
 */

//
// C++
//

#include "SkDevice_Compute.h"

//
//
//

#if SK_SUPPORT_GPU_COMPUTE

//
// C++
//

#include "SkImageInfo.h"
#include "SkDraw.h"
#include "SkMatrix.h"
#include "SkPath.h"

//
// C
//

#ifdef __cplusplus
extern "C" {
#endif

#include "../spinel/spinel/color.h"
#include "../compute/skc/skc.h"

#ifdef __cplusplus
}
#endif

//
//
//

SkDevice_Compute::SkDevice_Compute(sk_sp<SkContext_Compute> compute, int w, int h)
    : SkClipStackDevice(SkImageInfo::MakeN32Premul(w,h), SkSurfaceProps(0,kUnknown_SkPixelGeometry))
    , fCompute(std::move(compute))
{
  fTopCTM = this->ctm();
  fTransformWeakref = SKC_WEAKREF_INVALID;

  fClipWeakref = SKC_WEAKREF_INVALID;

  skc_err err;

  //
  // create a composition
  //
#define LAYER_COUNT (1<<14)

  err = skc_composition_create(fCompute->context, &fComposition);
  SKC_ERR_CHECK(err);

    // Is this correct?
    int clipRect[] = { 0, 0, w - 1, h - 1 };
  err = skc_composition_clip_set(fComposition, clipRect);
  SKC_ERR_CHECK(err);

  //
  // create styling
  //
  err = skc_styling_create(fCompute->context,
                           LAYER_COUNT,
                           10,
                           2 * 1024 * 1024,
                           &fStyling);

  //
  // create a path builder
  //
  err = skc_path_builder_create(fCompute->context, &fPB);
  SKC_ERR_CHECK(err);

  //
  // create a raster builder
  //
  err = skc_raster_builder_create(fCompute->context, &fRB);
  SKC_ERR_CHECK(err);

  //
  // create the simplest styling group that encloses all layers
  //
  styling_group_init();
}


//
//
//

SkDevice_Compute::~SkDevice_Compute() {
    skc_err err;

    err = skc_raster_builder_release(fRB);
    SKC_ERR_CHECK(err);

    err = skc_path_builder_release(fPB);
    SKC_ERR_CHECK(err);

    err = skc_styling_dispose(fStyling);
    SKC_ERR_CHECK(err);

    err = skc_composition_dispose(fComposition);
    SKC_ERR_CHECK(err);
}

//
//
//

void SkDevice_Compute::flush() {
    //
    // seal the styling and composition objects
    //
    skc_err err;

    err = skc_composition_seal(fComposition);
    SKC_ERR_CHECK(err);

    err = skc_styling_seal(fStyling);
    SKC_ERR_CHECK(err);

    //
    // we're going to block here -- API mismatch
    //

    //
    // render to surface
    //
    // note this implicitly seals composition and styling
    //
    err = skc_surface_render(fCompute->surface, fComposition, fStyling);
    SKC_ERR_CHECK(err);

    //
    // kick off pipeline and wait here -- not needed since skc_surface_reset() blocks
    //
    err = skc_surface_wait(fCompute->surface);
    SKC_ERR_CHECK(err);

    //
    // reset the surface -- implicitly waits for render to finish -- FIXME -- composition might be released too early
    //
    err = skc_surface_reset(fCompute->surface);
    SKC_ERR_CHECK(err);

    //
    // reset composition and styling
    //
    err = skc_composition_reset(fComposition);
    SKC_ERR_CHECK(err);

    err = skc_styling_reset(fStyling);
    SKC_ERR_CHECK(err);

    //
    //
    //
    styling_group_init();
}

//
//
//

#define SKC_STYLING_CMDS(...) SK_ARRAY_COUNT(__VA_ARGS__),__VA_ARGS__
#define SKC_GROUP_IDS(...)    SK_ARRAY_COUNT(__VA_ARGS__),__VA_ARGS__

void SkDevice_Compute::styling_group_init() {
    skc_styling_group_alloc(fStyling, &fGroupID);
    fParents.push_back(fGroupID);

    // ENTER
    skc_styling_cmd_t const styling_cmds_enter[] = {
        SKC_STYLING_CMD_OP_COVER_ZERO_ACC,
        SKC_STYLING_CMD_OP_COLOR_ZERO_ACC | SKC_STYLING_CMD_OP_IS_FINAL
    };
    skc_styling_group_enter(fStyling, fGroupID, SKC_STYLING_CMDS(styling_cmds_enter));

    skc_group_id const group_id_parents[] = { fGroupID };
    skc_styling_group_parents(fStyling, fGroupID, SKC_GROUP_IDS(group_id_parents));

    // RANGE
    skc_styling_group_range_lo(fStyling, fGroupID, 0);
    skc_styling_group_range_hi(fStyling, fGroupID, LAYER_COUNT-1);

    // LEAVE
    skc_styling_cmd_t const styling_cmds_leave[] = {
        SKC_STYLING_CMD_OP_SURFACE_COMPOSITE | SKC_STYLING_CMD_OP_IS_FINAL
    };
    skc_styling_group_leave(fStyling, fGroupID, SKC_STYLING_CMDS(styling_cmds_leave));

    // START
    fGroupLayerID = LAYER_COUNT-1;
}

//
//
//

#define SK_SCALE_F32      (1.0f/255.0f)
#define SK_TO_RGBA_F32(c) { SK_SCALE_F32 * SkColorGetR(c),      \
                            SK_SCALE_F32 * SkColorGetG(c),      \
                            SK_SCALE_F32 * SkColorGetB(c),      \
                            SK_SCALE_F32 * SkColorGetA(c) }
//
//
//

void SkDevice_Compute::path_rasterize_and_place(const SkPaint&   paint,
                                                const skc_path_t path,
                                                const SkMatrix*  prePathMatrix) {
    float transform[9];
    const SkMatrix& ctm = fTopCTM;
    SkMatrix tmp;

    if (prePathMatrix) {
        tmp.setConcat(ctm, *prePathMatrix);
    }
    transform[0] = tmp.get(SkMatrix::kMScaleX);
    transform[1] = tmp.get(SkMatrix::kMSkewX );
    transform[2] = tmp.get(SkMatrix::kMTransX);
    transform[3] = tmp.get(SkMatrix::kMSkewY );
    transform[4] = tmp.get(SkMatrix::kMScaleY);
    transform[5] = tmp.get(SkMatrix::kMTransY);
    transform[6] = tmp.get(SkMatrix::kMPersp0);
    transform[7] = tmp.get(SkMatrix::kMPersp1);
    transform[8] = tmp.get(SkMatrix::kMPersp2);

    skc_transform_weakref_t& transform_weakref = fTransformWeakref;
    //

    // always invalid for now
    //
    skc_raster_clip_weakref_t clip_weakref = fClipWeakref;

    // TODO Support arbitrary path clip?
    SkRect devClip = SkRect::Make(this->devClipBounds());
    const float clip[] = { devClip.fLeft, devClip.fTop, devClip.fRight, devClip.fBottom };

    //
    //
    //
    skc_err      err;
    skc_raster_t raster;

    err = skc_raster_begin(fRB);
    err = skc_raster_add_filled(fRB, path, &transform_weakref, transform, &clip_weakref, clip);
    err = skc_raster_end(fRB, &raster);

    //
    // can release path handle now because it is being referenced by raster
    //
    err = skc_path_release(fCompute->context, path);

    //
    // style the path
    //
    skc_styling_cmd_t cmds[1 + 3 + 1];

    cmds[0]                      = SKC_STYLING_CMD_OP_COVER_NONZERO;
    cmds[SK_ARRAY_COUNT(cmds)-1] = SKC_STYLING_CMD_OP_BLEND_OVER | SKC_STYLING_CMD_OP_IS_FINAL;

    {
        SkColor4f rgba = paint.getColor4f().premul();

        skc_styling_layer_fill_solid_encoder(cmds+1, rgba.vec());

        skc_styling_group_layer(fStyling, fGroupID, fGroupLayerID, SKC_STYLING_CMDS(cmds));
    }

    err = skc_composition_place(fComposition, fGroupLayerID, raster, 0, 0);

    //
    // can release raster handle now because it is being referenced by composition
    //
    err = skc_raster_release(fCompute->context, raster);

    SkASSERT(err == SKC_ERR_SUCCESS);

    fGroupLayerID -= 1;
}

//
//
//

void SkDevice_Compute::path_add(const SkPaint&  paint,
                                const SkPath&   path,
                                const SkMatrix* prePathMatrix) {
  skc_err err;

  err = skc_path_begin(fPB);

#if 0
  SkPath::Iter    pi(path,false);
#else
  SkPath::RawIter pi(path); // this seems to work fine for now
#endif

  SkPoint xy0;

  //
  // build path
  //
  while (true)
    {
      SkPoint            pts[4];
      SkPath::Verb const verb = pi.next(pts);

      switch (verb)
        {
        case SkPath::kMove_Verb:
	  xy0 = pts[0];
          err = skc_path_move_to(fPB,
                                 pts[0].x(),pts[0].y());
          continue;

        case SkPath::kLine_Verb:
          err = skc_path_line_to(fPB,
                                 pts[1].x(),pts[1].y());
          continue;

        case SkPath::kQuad_Verb:
          err = skc_path_quad_to(fPB,
                                 pts[1].x(),pts[1].y(),
                                 pts[2].x(),pts[2].y());
          continue;

        case SkPath::kConic_Verb: // <--------------------- FIXME
          err = skc_path_line_to(fPB,
                                 pts[2].x(),pts[2].y());
          continue;

        case SkPath::kCubic_Verb:
          err = skc_path_cubic_to(fPB,
                                  pts[1].x(),pts[1].y(),
                                  pts[2].x(),pts[2].y(),
                                  pts[3].x(),pts[3].y());
          continue;

        case SkPath::kClose_Verb:
          err = skc_path_line_to(fPB,xy0.x(),xy0.y());
          continue;

        case SkPath::kDone_Verb:
          break;
        }

      //
      // otherwise, kDone_Verb breaks out of while loop
      //
      break;
    }

  //
  // seal the path
  //
  skc_path_t skc_path;

  err = skc_path_end(fPB,&skc_path);

  //
  // rasterize the path and place it in a composition
  //
  path_rasterize_and_place(paint,skc_path,prePathMatrix);

  SkASSERT(err == SKC_ERR_SUCCESS);
}

//
//
//

void
SkDevice_Compute::circles_add(
			      const SkPaint  & paint,
			      const SkPoint    points[],
			      int32_t  const   count,
			      SkScalar const   radius)
{
#define CIRCLE_KAPPA    0.55228474983079339840f // moar digits!

#define CIRCLE_RADIUS_X radius
#define CIRCLE_RADIUS_Y radius

#define CIRCLE_KAPPA_X  (CIRCLE_RADIUS_X * CIRCLE_KAPPA)
#define CIRCLE_KAPPA_Y  (CIRCLE_RADIUS_Y * CIRCLE_KAPPA)

  //
  // use a 4 Bezier approximation
  //
  float const circle[] =
    {
      0.0f,             +CIRCLE_RADIUS_Y,   // move_to

      +CIRCLE_KAPPA_X,  +CIRCLE_RADIUS_Y,   // cubic_to
      +CIRCLE_RADIUS_X, +CIRCLE_KAPPA_Y,
      +CIRCLE_RADIUS_X,  0.0f,

      +CIRCLE_RADIUS_X, -CIRCLE_KAPPA_Y,    // cubic_to
      +CIRCLE_KAPPA_X,  -CIRCLE_RADIUS_Y,
      0.0f,             -CIRCLE_RADIUS_Y,

      -CIRCLE_KAPPA_X,  -CIRCLE_RADIUS_Y,   // cubic_to
      -CIRCLE_RADIUS_X, -CIRCLE_KAPPA_Y,
      -CIRCLE_RADIUS_X, 0.0f,

      -CIRCLE_RADIUS_X, +CIRCLE_KAPPA_Y,    // cubic_to
      -CIRCLE_KAPPA_X,  +CIRCLE_RADIUS_Y,
      0.0f,             +CIRCLE_RADIUS_Y
    };

#define CXLAT(x,y,t) circle[x]+t.fX,circle[y]+t.fY

  //
  //
  //

  skc_err err;

  err = skc_path_begin(fPB);

  //
  //
  //
  for (int32_t ii=0; ii<count; ii++)
    {
      SkPoint const p = points[ii];

      err = skc_path_move_to(fPB,
			     CXLAT(0,1,p));

      err = skc_path_cubic_to(fPB,
			      CXLAT(2,3,p),
			      CXLAT(4,5,p),
			      CXLAT(6,7,p));

      err = skc_path_cubic_to(fPB,
			      CXLAT(8, 9,p),
			      CXLAT(10,11,p),
			      CXLAT(12,13,p));

      err = skc_path_cubic_to(fPB,
			      CXLAT(14,15,p),
			      CXLAT(16,17,p),
			      CXLAT(18,19,p));

      err = skc_path_cubic_to(fPB,
			      CXLAT(20,21,p),
			      CXLAT(22,23,p),
			      CXLAT(24,25,p));
    }

  //
  // seal the path
  //
  skc_path_t skc_path;

  err = skc_path_end(fPB,&skc_path);

  //
  // rasterize the path and place it in a composition
  //
  path_rasterize_and_place(paint,skc_path,NULL);

  SkASSERT(err == SKC_ERR_SUCCESS);
}

//
//
//

void
SkDevice_Compute::squares_add(
			      const SkPaint  & paint,
			      const SkPoint    points[],
			      int32_t  const   count,
			      SkScalar const   radius)
{
  float const square[] =
    {
      -radius,+radius, // move_to
      +radius,+radius, // line_to
      +radius,-radius, // line_to
      -radius,-radius, // line_to
      -radius,+radius  // line_to
    };

#define SXLAT(x,y,t) square[x]+t.fX,square[y]+t.fY

  //
  //
  //

  skc_err err;

  err = skc_path_begin(fPB);

  //
  //
  //
  for (int32_t ii=0; ii<count; ii++)
    {
      SkPoint const p = points[ii];

      err = skc_path_move_to(fPB,SXLAT(0,1,p));
      err = skc_path_line_to(fPB,SXLAT(2,3,p));
      err = skc_path_line_to(fPB,SXLAT(4,5,p));
      err = skc_path_line_to(fPB,SXLAT(6,7,p));
      err = skc_path_line_to(fPB,SXLAT(8,9,p));
    }

  //
  // seal the path
  //
  skc_path_t skc_path;

  err = skc_path_end(fPB,&skc_path);

  //
  // rasterize the path and place it in a composition
  //
  path_rasterize_and_place(paint,skc_path,NULL);

  SkASSERT(err == SKC_ERR_SUCCESS);
}

//
// FIXME -- THIS IS NOT CORRECT
//
// Need to implement butt, round, square caps
//

void
SkDevice_Compute::line_stroked_butt(SkPoint  const xy0,
				    SkPoint  const xy1,
				    SkScalar const radius)
{
  float const dx    = xy1.fX - xy0.fX;
  float const dy    = xy1.fY - xy0.fY;

  float const hypot = hypotf(dx,dy);

  // FIXME -- what's practical here?
  if (hypot == 0.0f)
    return;

  float const scale = radius / hypot;

  float const rx    = dy * scale;
  float const ry    = dx * scale;

  skc_err err;

  err = skc_path_move_to(fPB,xy0.fX-rx,xy0.fY+ry);
  err = skc_path_line_to(fPB,xy1.fX-rx,xy1.fY+ry);
  err = skc_path_line_to(fPB,xy1.fX+rx,xy1.fY-ry);
  err = skc_path_line_to(fPB,xy0.fX+rx,xy0.fY-ry);
  err = skc_path_line_to(fPB,xy0.fX-rx,xy0.fY+ry);

  SkASSERT(err == SKC_ERR_SUCCESS);
}

void
SkDevice_Compute::lines_stroked_add(
				    const SkPaint  & paint,
				    const SkPoint    points[],
				    int32_t  const   count,
				    SkScalar const   radius)
{
  skc_err err;

  err = skc_path_begin(fPB);

  //
  //
  //
  for (int32_t ii=0; ii<count; ii+=2)
    line_stroked_butt(points[ii],points[ii+1],radius);

  //
  // seal the path
  //
  skc_path_t skc_path;

  err = skc_path_end(fPB,&skc_path);

  //
  // rasterize the path and place it in a composition
  //
  path_rasterize_and_place(paint,skc_path,NULL);

  SkASSERT(err == SKC_ERR_SUCCESS);
}


//
//
//

//  drawPaint is really just a short-cut for drawRect(wide_open, paint)
//  so we have to respect everything (but stroking and maskfilter) in the paint
//  - color | shader
//  - colorFilter
//  - blendmode
//  - etc.
void SkDevice_Compute::drawPaint(const SkPaint& paint) {
  //
  // clear the surface -- will be postponed until render is complete
  //
  SkColor const c       = paint.getColor();
  float         rgba[4] = SK_TO_RGBA_F32(c);

  skc_surface_clear(fCompute->surface,rgba);
}

void SkDevice_Compute::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[],
                                  const SkPaint& paint) {
    if (count == 0) {
        return;
    }

    const SkScalar radius = paint.getStrokeWidth() * 0.5f;

    /*
     *  drawPoints draws each element (point, line) separately. This means our bulk-adding into the
     *  same raster is not valid for most blendmodes.
     */
    switch (mode) {
        case SkCanvas::kPoints_PointMode: {
            if (paint.getStrokeCap() == SkPaint::kRound_Cap) {
                circles_add(paint, points, (int32_t)count, radius);
            } else {
                squares_add(paint, points,(int32_t)count, radius);
            }
        } break;

        case SkCanvas::kLines_PointMode: {
            if (count <= 1) {
                return;
            }
            lines_stroked_add(paint, points, (int32_t)count & ~1, radius);
        } break;

        case SkCanvas::kPolygon_PointMode: {
            SkPoint xy0 = points[0];
            skc_err err = skc_path_begin(fPB);

            for (size_t i = 0; i < count; ++i) {
                const SkPoint xy1 = points[i];
                line_stroked_butt(xy0, xy1, radius);
                xy0 = xy1;
            }

            //
            // seal the path
            //
            skc_path_t skc_path;
            err = skc_path_end(fPB, &skc_path);

            //
            // rasterize the path and place it in a composition
            //
            path_rasterize_and_place(paint, skc_path, nullptr);

            SkASSERT(err == SKC_ERR_SUCCESS);
        } break;

        default:
            break;
    }
}

void SkDevice_Compute::drawRect(const SkRect& rect, const SkPaint& paint) {
    SkPath path;

    path.addRect(rect);
    this->drawPath(path, paint, nullptr, true);
}

void SkDevice_Compute::drawOval(const SkRect& oval, const SkPaint& paint) {
    SkPath path;

    path.addOval(oval);
    this->drawPath(path, paint, nullptr, true);
}

void SkDevice_Compute::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
    SkPath path;

    path.addRRect(rrect);
    this->drawPath(path, paint, nullptr, true);
}

void SkDevice_Compute::drawPath(const SkPath& path, const SkPaint& paint,
                                const SkMatrix* prePathMatrix, bool pathIsMutable) {
  if (paint.getStyle() == SkPaint::kFill_Style) {
      path_add(paint,path,prePathMatrix);
  } else {
      SkPath stroked;

#define SK_MAGIC_RES_SCALE 1024

        paint.getFillPath(path, &stroked, nullptr, SK_MAGIC_RES_SCALE);
        this->path_add(paint, stroked, prePathMatrix);
    }
}

void SkDevice_Compute::drawText(const void*    text,
                                size_t         length,
                                SkScalar       x,
                                SkScalar       y,
                                const SkPaint& paint) {
    SkPath outline;

    paint.getTextPath(text,length,x,y,&outline);
    this->drawPath(outline, paint, nullptr, true);
}

void
SkDevice_Compute::drawPosText(const void     * text,
                              size_t           length,
                              const SkScalar   pos[],
                              int              scalarsPerPos,
                              const SkPoint  & offset,
                              const SkPaint  & paint)
{
#if 0
  draw.drawPosText_asPaths((const char *)text,length,
			   pos,scalarsPerPos,offset,paint);
#endif
}

SkBaseDevice* SkDevice_Compute::onCreateDevice(const CreateInfo& cinfo, const SkPaint* paint) {
#ifdef SK_USE_COMPUTE_LAYER_GROUP
    return this->createLayerGroup(cinfo, paint);
#else
    // TODO return a new SkDevice_Compute when SkDevice_ComputeLayerGroup doesn't work
    return nullptr;
#endif
}

void SkDevice_Compute::drawDevice(SkBaseDevice* device, int left, int top, const SkPaint& paint) {
    // It seems that we won't support image filter until snapSpecial and drawSpecial are implemented
    // (SkCanvas.cpp will call drawSpecial when the paint has an image filter).
    SkASSERT(!paint.getImageFilter());

#ifdef SK_USE_COMPUTE_LAYER_GROUP
    // In case of SkDevice_ComputeLayerGroup, we close the group
    SkDevice_ComputeLayerGroup* layerDevice = static_cast<SkDevice_ComputeLayerGroup*>(device);
    SkASSERT(layerDevice->fRoot == this); // the layerDevice should belong to this root device
    SkASSERT(layerDevice->fGroupID == fGroupID); // the layerDevice should be the top device

    // left, top should be the same as the origin,
    // and we can ignore them because we have no offscreen buffer.
    SkASSERT(SkIPoint::Make(left, top) == device->getOrigin());

    // close the group and pop the top device
    skc_styling_group_range_lo(fStyling, fGroupID, fGroupLayerID + 1);
    fGroupID = fParents.back();
    fParents.pop_back();
#else
    // TODO handle the case where the device is a SkDevice_Compute rather than
    // SkDevice_ComputeLayerGroup (in which case an offscreen buffer is created).
#endif
}

#ifdef SK_USE_COMPUTE_LAYER_GROUP

SkDevice_ComputeLayerGroup* SkDevice_Compute::createLayerGroup(const CreateInfo& cinfo,
        const SkPaint* paint) {
    return new SkDevice_ComputeLayerGroup(this, cinfo, paint);
}

void SkDevice_Compute::onCtmChanged() {
    fTopCTM = this->ctm();
    fTransformWeakref = SKC_WEAKREF_INVALID;
}

SkDevice_ComputeLayerGroup::SkDevice_ComputeLayerGroup(SkDevice_Compute* root,
        const CreateInfo& cinfo, const SkPaint* paint)
        : SkBaseDevice(SkImageInfo::MakeN32Premul(cinfo.fInfo.width(), cinfo.fInfo.height()),
                       SkSurfaceProps(0,kUnknown_SkPixelGeometry)) {
    // TODO clip the group using cinfo; handle the paint's alpha and maybe color filter?

    // Create a new group. We'll restore the previous group during onRestore.
    skc_styling_group_alloc(fRoot->fStyling, &fRoot->fGroupID);
    fRoot->fParents.push_back(fRoot->fGroupID);
    fGroupID = fRoot->fGroupID;

    // ENTER
    skc_styling_cmd_t const styling_cmds_enter[] = {
        SKC_STYLING_CMD_OP_COVER_ZERO_ACC,
        SKC_STYLING_CMD_OP_COLOR_ZERO_ACC
    };
    skc_styling_group_enter(fRoot->fStyling, fRoot->fGroupID, SKC_STYLING_CMDS(styling_cmds_enter));

    skc_styling_group_parents(fRoot->fStyling, fRoot->fGroupID, fRoot->fParents.count(),
            fRoot->fParents.begin());

    // RANGE
    // We'll set range_lo at restore
    skc_styling_group_range_hi(fRoot->fStyling, fRoot->fGroupID, fRoot->fGroupLayerID);

    // LEAVE
    skc_styling_cmd_t const styling_cmds_leave[] = {
        SKC_STYLING_CMD_OP_SURFACE_COMPOSITE
    };
    skc_styling_group_leave(fRoot->fStyling, fRoot->fGroupID, SKC_STYLING_CMDS(styling_cmds_leave));
}

void SkDevice_ComputeLayerGroup::drawDevice(SkBaseDevice* device, int left, int top,
        const SkPaint& paint) {
    fRoot->drawDevice(device, left, top, paint); // the root will properly close the group
}

SkBaseDevice* SkDevice_ComputeLayerGroup::onCreateDevice(const CreateInfo& cinfo,
        const SkPaint* paint) {
    return fRoot->createLayerGroup(cinfo, paint);
}

void SkDevice_ComputeLayerGroup::onCtmChanged() {
    this->sanityCheck();

    // Cancels the translation as we're not using an offscreen buffer
    const SkIPoint& origin = this->getOrigin();
    fRoot->fTopCTM = this->ctm();
    fRoot->fTopCTM.postTranslate(SkIntToScalar(origin.fX), SkIntToScalar(origin.fY));
    fRoot->fTransformWeakref = SKC_WEAKREF_INVALID;
}

void SkDevice_ComputeLayerGroup::onSave() {
    this->sanityCheck();
    fRoot->onSave();
}

void SkDevice_ComputeLayerGroup::onRestore() {
    this->sanityCheck();
    fRoot->onRestore();
}

void SkDevice_ComputeLayerGroup::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
    this->sanityCheck();
    fRoot->fClipStack.clipRect(rect, fRoot->fTopCTM, op, aa);
    fRoot->fClipWeakref = SKC_WEAKREF_INVALID;
}

void SkDevice_ComputeLayerGroup::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
    this->sanityCheck();
    fRoot->fClipStack.clipRRect(rrect, fRoot->fTopCTM, op, aa);
    fRoot->fClipWeakref = SKC_WEAKREF_INVALID;
}

void SkDevice_ComputeLayerGroup::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
    this->sanityCheck();
    fRoot->fClipStack.clipPath(path, fRoot->fTopCTM, op, aa);
    fRoot->fClipWeakref = SKC_WEAKREF_INVALID;
}

void SkDevice_ComputeLayerGroup::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    this->sanityCheck();
    fRoot->onClipRegion(deviceRgn, op);
}

void SkDevice_ComputeLayerGroup::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {
    this->sanityCheck();
    fRoot->onSetDeviceClipRestriction(mutableClipRestriction);
}

#endif // SK_USE_COMPUTE_LAYER_GROUP

#endif
