root/native_client_sdk/src/libraries/ppapi_simple/ps_context_2d.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PSContext2DAllocate
  2. PSContext2DFree
  3. PSContext2DGetNativeImageDataFormat
  4. PSContext2DHandleEvent
  5. PSContext2DGetBuffer
  6. PSContext2DSwapBuffer

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

#include <stdlib.h>
#include <string.h>

#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_size.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/c/ppb_image_data.h"
#include "ppapi/c/ppb_instance.h"
#include "ppapi/c/ppb_view.h"
#include "ppapi/cpp/image_data.h"

#include "ppapi_simple/ps.h"
#include "ppapi_simple/ps_context_2d.h"
#include "ppapi_simple/ps_event.h"
#include "ppapi_simple/ps_instance.h"
#include "ppapi_simple/ps_interface.h"

PSContext2D_t* PSContext2DAllocate(PP_ImageDataFormat format) {
  PSContext2D_t* ctx = (PSContext2D_t*) malloc(sizeof(PSContext2D_t));
  memset(ctx, 0, sizeof(PSContext2D_t));

  ctx->format = format;
  return ctx;
}

void PSContext2DFree(PSContext2D_t* ctx) {
  if (ctx->graphic_2d) {
    PSInterfaceCore()->ReleaseResource(ctx->graphic_2d);
    ctx->graphic_2d = 0;
  }
  if (ctx->image) {
    PSInterfaceCore()->ReleaseResource(ctx->image);
    ctx->image = 0;
  }
  free(ctx);
}

PP_ImageDataFormat PSContext2DGetNativeImageDataFormat() {
  return PSInterfaceImageData()->GetNativeImageDataFormat();
}

// Update the 2D context if the message is appropriate, returning non-zero
// if the event was consumed.
int PSContext2DHandleEvent(PSContext2D_t* ctx, PSEvent* event) {
  switch(event->type) {
    case PSE_INSTANCE_DIDCHANGEVIEW: {
      struct PP_Rect rect;

      PSInterfaceView()->GetRect(event->as_resource, &rect);
      PSInterfaceCore()->ReleaseResource(ctx->graphic_2d);
      ctx->bound = 0;
      ctx->width = rect.size.width;
      ctx->height = rect.size.height;

      // Create an opaque graphic context of the specified size.
      ctx->graphic_2d =
          PSInterfaceGraphics2D()->Create(PSGetInstanceId(), &rect.size,
                                          PP_TRUE);

      // Bind the context to so that draws will be visible.
      if (ctx->graphic_2d) {
        ctx->bound =
            PSInterfaceInstance()->BindGraphics(PSGetInstanceId(),
                                                ctx->graphic_2d);
      }

      // Typically this resource would not be allocated yet, but just in case
      // throw it away, to force a new allocation when GetBuffer is called.
      if (ctx->image) {
        PSInterfaceCore()->ReleaseResource(ctx->image);
        ctx->image = 0;
      }

      return 1;
    }
    default: break;
  }

  return 0;
}


// Allocates (if needed) a new image context which will be swapped in when
// drawing is complete.  PSContextGetBuffer and PSContext2DSwapBuffer
// implemented the suggested image/graphic_2d use specified in the
// ppb_graphics_2d header.
int PSContext2DGetBuffer(PSContext2D_t* ctx) {
  if (!ctx->bound) return 0;

  // Check if we are already holding an image
  if (ctx->image) return 1;

  PP_Size size;
  size.width = ctx->width;
  size.height = ctx->height;

  // Allocate a new image resource with the specified size and format, but
  // do not ZERO out the buffer first since we will fill it.
  PP_Resource image =
      PSInterfaceImageData()->Create(PSGetInstanceId(), ctx->format, &size,
                                     PP_FALSE);

  if (0 == image) {
    PSInstance::GetInstance()->Error("Unable to create 2D image.\n");
    return 0;
  }

  // Get the stride
  struct PP_ImageDataDesc desc;
  PSInterfaceImageData()->Describe(image, &desc);

  ctx->image = image;
  ctx->data = static_cast<uint32_t*>(PSInterfaceImageData()->Map(image));
  ctx->stride = desc.stride;
  return 1;
}

int PSContext2DSwapBuffer(PSContext2D_t* ctx) {
  if (ctx->bound && ctx->image) {
    PSInterfaceImageData()->Unmap(ctx->image);
    PSInterfaceGraphics2D()->ReplaceContents(ctx->graphic_2d, ctx->image);
    PSInterfaceGraphics2D()->Flush(ctx->graphic_2d, PP_BlockUntilComplete());
    PSInterfaceCore()->ReleaseResource(ctx->image);

    ctx->image = 0;
    ctx->stride = 0;
    ctx->data = NULL;
    return 1;
  }
  return 0;
}


/* [<][>][^][v][top][bottom][index][help] */