// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @defgroup graphics Graphics
 *
 * @{
 */

/**
 * @file
 * @brief  Graphics drawing library
 */
#include <assert.h>
#include <lib/zbi-format/graphics.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <zircon/compiler.h>
#include <zircon/syscalls.h>

#include <gfx-common/gfx-common.h>

#define GFX_LOG(ctx, fmt, ...)                                     \
  do {                                                             \
    (ctx)->log("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
  } while (0)

#define GFX_ASSERT_MSG(ctx, cond, fmt, ...)                           \
  do {                                                                \
    if (!(cond)) {                                                    \
      (ctx)->panic("[%s:%d]" fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
    }                                                                 \
  } while (0)

#define GFX_ASSERT(ctx, cond)                                                    \
  do {                                                                           \
    if (!(cond)) {                                                               \
      (ctx)->panic("[%s:%d] failed assertion: " #cond "\n", __FILE__, __LINE__); \
    }                                                                            \
  } while (0)

namespace {

struct Rgb888 {
  Rgb888() = default;
  explicit Rgb888(uint32_t rgba) {
    b = rgba & 0xff;
    g = (rgba & 0xff00) >> 8;
    r = (rgba & 0xff0000) >> 16;
  }
  uint32_t ToRgba32() const { return b | (g << 8) | (r << 16) | (0xff << 24); }

  uint8_t b = 0;
  uint8_t g = 0;
  uint8_t r = 0;
} __attribute__((packed));

}  // namespace

// Convert a 32bit ARGB image to its respective gamma corrected grayscale value.
static uint32_t ARGB8888_to_Luma(uint32_t in) {
  uint8_t out;

  uint32_t blue = (in & 0xFF) * 74;
  uint32_t green = ((in >> 8) & 0xFF) * 732;
  uint32_t red = ((in >> 16) & 0xFF) * 218;

  uint32_t intensity = red + blue + green;

  out = (intensity >> 10) & 0xFF;

  return out;
}

static uint32_t ARGB8888_to_RGB888(uint32_t in) { return in & 0xFFFFFF; }

static uint32_t ARGB8888_to_RGB565(uint32_t in) {
  uint32_t out;

  out = (in >> 3) & 0x1f;            // b
  out |= ((in >> 10) & 0x3f) << 5;   // g
  out |= ((in >> 19) & 0x1f) << 11;  // r

  return out;
}

static uint32_t ARGB8888_to_RGB332(uint32_t in) {
  uint32_t out = 0;

  out = (in >> 6) & 0x3;           // b
  out |= ((in >> 13) & 0x7) << 2;  // g
  out |= ((in >> 21) & 0x7) << 5;  // r

  return out;
}

static uint32_t ARGB8888_to_RGB2220(uint32_t in) {
  uint32_t out = 0;

  out = ((in >> 6) & 0x3) << 2;
  out |= ((in >> 14) & 0x3) << 4;
  out |= ((in >> 22) & 0x3) << 6;

  return out;
}

/**
 * @brief  Copy a rectangle of pixels from one part of the display to another.
 */
void gfx_copyrect(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
                  uint32_t x2, uint32_t y2) {
  // trim
  if (x >= surface->width)
    return;
  if (x2 >= surface->width)
    return;
  if (y >= surface->height)
    return;
  if (y2 >= surface->height)
    return;
  if (width == 0 || height == 0)
    return;

  // clip the width to src or dest
  if (x + width > surface->width)
    width = surface->width - x;
  if (x2 + width > surface->width)
    width = surface->width - x2;

  // clip the height to src or dest
  if (y + height > surface->height)
    height = surface->height - y;
  if (y2 + height > surface->height)
    height = surface->height - y2;

  surface->copyrect(surface, x, y, width, height, x2, y2);
}

/**
 * @brief  Fill a rectangle on the screen with a constant color.
 */
void gfx_fillrect(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
                  uint32_t color) {
  GFX_LOG(surface->ctx, "surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, height,
          color);
  // trim
  if (unlikely(x >= surface->width))
    return;
  if (y >= surface->height)
    return;
  if (width == 0 || height == 0)
    return;

  // clip the width
  if (x + width > surface->width)
    width = surface->width - x;

  // clip the height
  if (y + height > surface->height)
    height = surface->height - y;

  surface->fillrect(surface, x, y, width, height, color);
}

/**
 * @brief  Write a single pixel to the screen.
 */
void gfx_putpixel(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t color) {
  if (unlikely(x >= surface->width))
    return;
  if (y >= surface->height)
    return;

  surface->putpixel(surface, x, y, color);
}

template <typename T>
static void putpixel(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t color) {
  T* dest = static_cast<T*>(surface->ptr) + (x + y * surface->stride);

  if (sizeof(T) == sizeof(uint32_t)) {
    *dest = static_cast<T>(color);
  } else {
    // colors come in in ARGB 8888 form, flatten them
    *dest = static_cast<T>(surface->translate_color(color));
  }
}

template <typename T>
static void copyrect(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
                     uint32_t x2, uint32_t y2) {
  // copy
  const T* src = static_cast<const T*>(surface->ptr) + (x + y * surface->stride);
  T* dest = static_cast<T*>(surface->ptr) + (x2 + y2 * surface->stride);
  uint32_t stride_diff = surface->stride - width;

  if (dest < src) {
    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += stride_diff;
      src += stride_diff;
    }
  } else {
    // copy backwards
    src += (height - 1) * surface->stride + (width - 1);
    dest += (height - 1) * surface->stride + (width - 1);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest--;
        src--;
      }
      dest -= stride_diff;
      src -= stride_diff;
    }
  }
}

template <typename T>
static void fillrect(gfx_surface* surface, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
                     uint32_t _color) {
  T* dest = static_cast<T*>(surface->ptr) + (x + y * surface->stride);
  uint32_t stride_diff = surface->stride - width;

  T color;
  if (sizeof(_color) == sizeof(color)) {
    color = static_cast<T>(_color);
  } else {
    color = static_cast<T>(surface->translate_color(_color));
  }

  uint32_t i, j;
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      *dest = color;
      dest++;
    }
    dest += stride_diff;
  }
}

void gfx_line(gfx_surface* surface, uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2,
              uint32_t color) {
  if (unlikely(x1 >= surface->width))
    return;
  if (unlikely(x2 >= surface->width))
    return;

  if (y1 >= surface->height)
    return;
  if (y2 >= surface->height)
    return;

  int dx = x2 - x1;
  int dy = y2 - y1;

  int sdx = (0 < dx) - (dx < 0);
  int sdy = (0 < dy) - (dy < 0);

  uint32_t dxabs = (dx > 0) ? dx : -dx;
  uint32_t dyabs = (dy > 0) ? dy : -dy;

  uint32_t x = dyabs >> 1;
  uint32_t y = dxabs >> 1;

  uint32_t px = x1;
  uint32_t py = y1;

  if (dxabs >= dyabs) {
    // mostly horizontal line.
    for (uint32_t i = 0; i < dxabs; i++) {
      y += dyabs;
      if (y >= dxabs) {
        y -= dxabs;
        py += sdy;
      }
      px += sdx;
      surface->putpixel(surface, px, py, color);
    }
  } else {
    // mostly vertical line.
    for (uint32_t i = 0; i < dyabs; i++) {
      x += dxabs;
      if (x >= dyabs) {
        x -= dyabs;
        px += sdx;
      }
      py += sdy;
      surface->putpixel(surface, px, py, color);
    }
  }
}

static uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src) {
  uint32_t cdest[3];
  uint32_t csrc[3];

  uint32_t srca;
  uint32_t srcainv;

  srca = (src >> 24) & 0xff;
  if (srca == 0) {
    return dest;
  } else if (srca == 255) {
    return src;
  }
  srca++;
  srcainv = (255 - srca);

  cdest[0] = (dest >> 16) & 0xff;
  cdest[1] = (dest >> 8) & 0xff;
  cdest[2] = (dest >> 0) & 0xff;

  csrc[0] = (src >> 16) & 0xff;
  csrc[1] = (src >> 8) & 0xff;
  csrc[2] = (src >> 0) & 0xff;

  //    if (srca > 0)
  //        printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], csrc[2], cdest[0],
  //        cdest[1], cdest[2], srca, srcainv);

  uint32_t cres[3];

  cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256);
  cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256);
  cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256);

  return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]);
}

/**
 * @brief  Copy pixels from source to dest.
 *
 * Currently does not support alpha channel.
 */
void gfx_surface_blend(struct gfx_surface* target, struct gfx_surface* source, uint32_t destx,
                       uint32_t desty) {
  gfx_blend(target, source, 0, 0, source->width, source->height, destx, desty);
}

void gfx_blend(struct gfx_surface* target, struct gfx_surface* source, uint32_t srcx, uint32_t srcy,
               uint32_t width, uint32_t height, uint32_t destx, uint32_t desty) {
  const gfx_context* ctx = source->ctx;
  GFX_ASSERT(ctx, target->format == source->format);
  GFX_LOG(ctx, "target %p, source %p, destx %u, desty %u\n", target, source, destx, desty);

  if (destx >= target->width)
    return;
  if (desty >= target->height)
    return;

  if (srcx >= source->width)
    return;
  if (srcy >= source->height)
    return;

  if (destx + width > target->width)
    width = target->width - destx;
  if (desty + height > target->height)
    height = target->height - desty;

  if (srcx + width > source->width)
    width = source->width - srcx;
  if (srcy + height > source->height)
    height = source->height - srcy;

  // XXX total hack to deal with various blends
  if (source->format == ZBI_PIXEL_FORMAT_RGB_565 && target->format == ZBI_PIXEL_FORMAT_RGB_565) {
    // 16 bit to 16 bit
    const uint16_t* src = static_cast<uint16_t*>(source->ptr) + (srcx + srcy * source->stride);
    uint16_t* dest = static_cast<uint16_t*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZBI_PIXEL_FORMAT_ARGB_8888 &&
             target->format == ZBI_PIXEL_FORMAT_ARGB_8888) {
    // both are 32 bit modes, both alpha
    const uint32_t* src = static_cast<uint32_t*>(source->ptr) + (srcx + srcy * source->stride);
    uint32_t* dest = static_cast<uint32_t*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        // TODO(https://fxbug.dev/42165247): Currently it ignores destination alpha.
        // We should implement alpha blending correctly.
        *dest = alpha32_add_ignore_destalpha(*dest, *src);
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZBI_PIXEL_FORMAT_RGB_X888 &&
             target->format == ZBI_PIXEL_FORMAT_RGB_X888) {
    // both are 32 bit modes, no alpha
    const uint32_t* src = static_cast<uint32_t*>(source->ptr) + (srcx + srcy * source->stride);
    uint32_t* dest = static_cast<uint32_t*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZBI_PIXEL_FORMAT_ARGB_8888 &&
             target->format == ZBI_PIXEL_FORMAT_RGB_888) {
    // 32 bit to 24 bit modes, alpha to no-alpha
    const uint32_t* src = static_cast<uint32_t*>(source->ptr) + (srcx + srcy * source->stride);
    Rgb888* dest = static_cast<Rgb888*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        // TODO(https://fxbug.dev/42165247): Currently it ignores destination alpha.
        // We should implement alpha blending correctly.
        *dest = Rgb888(alpha32_add_ignore_destalpha(dest->ToRgba32(), *src));
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZBI_PIXEL_FORMAT_RGB_X888 &&
             target->format == ZBI_PIXEL_FORMAT_RGB_888) {
    // 32 bit to 24 bit modes, no alpha
    const uint32_t* src = static_cast<uint32_t*>(source->ptr) + (srcx + srcy * source->stride);
    Rgb888* dest = static_cast<Rgb888*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = Rgb888(*src);
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZBI_PIXEL_FORMAT_MONO_8 &&
             target->format == ZBI_PIXEL_FORMAT_MONO_8) {
    // both are 8 bit modes, no alpha
    const uint8_t* src = static_cast<uint8_t*>(source->ptr) + (srcx + srcy * source->stride);
    uint8_t* dest = static_cast<uint8_t*>(target->ptr) + (destx + desty * target->stride);
    uint32_t dest_stride_diff = target->stride - width;
    uint32_t source_stride_diff = source->stride - width;

    GFX_LOG(ctx, "w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    uint32_t i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else {
    GFX_ASSERT_MSG(
        ctx, false,
        "gfx_surface_blend: unimplemented colorspace combination (source %u target %u)\n",
        source->format, target->format);
  }
}

template <typename T>
static void putchar(gfx_surface* surface, const gfx_font_t* font, uint32_t ch, uint32_t x,
                    uint32_t y, uint32_t fg, uint32_t bg) {
  T* dest = static_cast<T*>(surface->ptr) + (x + y * surface->stride);

  const uint16_t* cdata = font->data + ch * font->height;
  uint32_t fw = font->width;
  for (uint32_t i = font->height; i > 0; i--) {
    uint16_t xdata = *cdata++;
    for (uint32_t j = fw; j > 0; j--) {
      *dest++ = static_cast<T>((xdata & 1) ? fg : bg);
      xdata = static_cast<uint16_t>(xdata >> 1);
    }
    dest += (surface->stride - fw);
  }
}

void gfx_putchar(gfx_surface* surface, const gfx_font_t* font, uint32_t ch, uint32_t x, uint32_t y,
                 uint32_t fg, uint32_t bg) {
  if (unlikely(ch > 127)) {
    return;
  }
  if (unlikely(x > (surface->width - font->width))) {
    return;
  }
  if (unlikely(y > (surface->height - font->height))) {
    return;
  }
  if (surface->translate_color) {
    fg = surface->translate_color(fg);
    bg = surface->translate_color(bg);
  }
  surface->putchar(surface, font, ch, x, y, fg, bg);
}

void gfx_copylines(gfx_surface* dst, gfx_surface* src, uint32_t srcy, uint32_t dsty,
                   uint32_t height) {
  if ((dst->stride != src->stride) || (dst->format != src->format)) {
    return;
  }
  if ((srcy >= src->height) || ((src->height - srcy) < height)) {
    return;
  }
  if ((dsty >= dst->height) || (dst->height - dsty) < height) {
    return;
  }
  memmove(reinterpret_cast<uint8_t*>(dst->ptr) + dsty * dst->stride * dst->pixelsize,
          reinterpret_cast<uint8_t*>(src->ptr) + srcy * src->stride * src->pixelsize,
          height * src->stride * src->pixelsize);
}

/**
 * @brief  Ensure all graphics rendering is sent to display
 */
void gfx_flush(gfx_surface* surface) {
  if (surface->flags & GFX_FLAG_FLUSH_CPU_CACHE)
    surface->ctx->flush_cache(surface->ptr, surface->len);

  if (surface->flush)
    surface->flush(0, surface->height - 1);
}

/**
 * @brief  Ensure that a sub-region of the display is up to date.
 */
void gfx_flush_rows(struct gfx_surface* surface, uint32_t start, uint32_t end) {
  if (start > end) {
    uint32_t temp = start;
    start = end;
    end = temp;
  }

  if (start >= surface->height)
    return;
  if (end >= surface->height)
    end = surface->height - 1;

  if (surface->flags & GFX_FLAG_FLUSH_CPU_CACHE) {
    uint32_t runlen = surface->stride * surface->pixelsize;
    surface->ctx->flush_cache(reinterpret_cast<uint8_t*>(surface->ptr) + start * runlen,
                              (end - start + 1) * runlen);
  }

  if (surface->flush)
    surface->flush(start, end);
}

/**
 * @brief  Create a new graphics surface object
 */
gfx_surface* gfx_create_surface_with_context(void* ptr, const gfx_context* ctx, uint32_t width,
                                             uint32_t height, uint32_t stride, gfx_format format,
                                             uint32_t flags) {
  gfx_surface* surface = static_cast<gfx_surface*>(calloc(1, sizeof(*surface)));
  if (surface == NULL)
    return NULL;
  surface->ctx = ctx;
  if (gfx_init_surface(surface, ptr, width, height, stride, format, flags)) {
    free(surface);
    return NULL;
  }
  return surface;
}

zx_status_t gfx_init_surface(gfx_surface* surface, void* ptr, uint32_t width, uint32_t height,
                             uint32_t stride, gfx_format format, uint32_t flags) {
  if ((width == 0) || (height == 0) || (stride < width)) {
    return ZX_ERR_INVALID_ARGS;
  }

  surface->flags = flags;
  surface->format = format;
  surface->width = width;
  surface->height = height;
  surface->stride = stride;
  surface->alpha = MAX_ALPHA;

  // set up some function pointers
  switch (format) {
    case ZBI_PIXEL_FORMAT_RGB_565:
      surface->translate_color = &ARGB8888_to_RGB565;
      surface->copyrect = &copyrect<uint16_t>;
      surface->fillrect = &fillrect<uint16_t>;
      surface->putpixel = &putpixel<uint16_t>;
      surface->putchar = &putchar<uint16_t>;
      surface->pixelsize = 2;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZBI_PIXEL_FORMAT_RGB_888:
      surface->translate_color = &ARGB8888_to_RGB888;
      surface->copyrect = &copyrect<Rgb888>;
      surface->fillrect = &fillrect<Rgb888>;
      surface->putpixel = &putpixel<Rgb888>;
      surface->putchar = &putchar<Rgb888>;
      surface->pixelsize = 3;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZBI_PIXEL_FORMAT_RGB_X888:
    case ZBI_PIXEL_FORMAT_ARGB_8888:
      surface->translate_color = NULL;
      surface->copyrect = &copyrect<uint32_t>;
      surface->fillrect = &fillrect<uint32_t>;
      surface->putpixel = &putpixel<uint32_t>;
      surface->putchar = &putchar<uint32_t>;
      surface->pixelsize = 4;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZBI_PIXEL_FORMAT_MONO_8:
      surface->translate_color = &ARGB8888_to_Luma;
      surface->copyrect = &copyrect<uint8_t>;
      surface->fillrect = &fillrect<uint8_t>;
      surface->putpixel = &putpixel<uint8_t>;
      surface->putchar = &putchar<uint8_t>;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZBI_PIXEL_FORMAT_RGB_332:
      surface->translate_color = &ARGB8888_to_RGB332;
      surface->copyrect = &copyrect<uint8_t>;
      surface->fillrect = &fillrect<uint8_t>;
      surface->putpixel = &putpixel<uint8_t>;
      surface->putchar = &putchar<uint8_t>;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZBI_PIXEL_FORMAT_RGB_2220:
      surface->translate_color = &ARGB8888_to_RGB2220;
      surface->copyrect = &copyrect<uint8_t>;
      surface->fillrect = &fillrect<uint8_t>;
      surface->putpixel = &putpixel<uint8_t>;
      surface->putchar = &putchar<uint8_t>;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    default:
      GFX_LOG(surface->ctx, "invalid graphics format\n");
      return ZX_ERR_INVALID_ARGS;
  }

  if (ptr == NULL) {
    // allocate a buffer
    ptr = malloc(surface->len);
    if (ptr == NULL) {
      return ZX_ERR_NO_MEMORY;
    }
    GFX_ASSERT(surface->ctx, ptr);
    surface->flags |= GFX_FLAG_FREE_ON_DESTROY;
  }
  surface->ptr = ptr;
  return ZX_OK;
}

/**
 * @brief  Destroy a graphics surface and free all resources allocated to it.
 *
 * @param  surface  Surface to destroy.  This pointer is no longer valid after
 *    this call.
 */
void gfx_surface_destroy(struct gfx_surface* surface) {
  if (surface->flags & GFX_FLAG_FREE_ON_DESTROY)
    free(surface->ptr);
  free(surface);
}
