Home | History | Annotate | Download | only in ppapi_simple
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #include "ppapi/c/pp_rect.h"
      9 #include "ppapi/c/pp_resource.h"
     10 #include "ppapi/c/pp_size.h"
     11 #include "ppapi/c/ppb_core.h"
     12 #include "ppapi/c/ppb_graphics_2d.h"
     13 #include "ppapi/c/ppb_image_data.h"
     14 #include "ppapi/c/ppb_instance.h"
     15 #include "ppapi/c/ppb_view.h"
     16 #include "ppapi/cpp/image_data.h"
     17 
     18 #include "ppapi_simple/ps.h"
     19 #include "ppapi_simple/ps_context_2d.h"
     20 #include "ppapi_simple/ps_event.h"
     21 #include "ppapi_simple/ps_instance.h"
     22 #include "ppapi_simple/ps_interface.h"
     23 
     24 PSContext2D_t* PSContext2DAllocate(PP_ImageDataFormat format) {
     25   PSContext2D_t* ctx = (PSContext2D_t*) malloc(sizeof(PSContext2D_t));
     26   memset(ctx, 0, sizeof(PSContext2D_t));
     27 
     28   ctx->format = format;
     29   return ctx;
     30 }
     31 
     32 void PSContext2DFree(PSContext2D_t* ctx) {
     33   if (ctx->graphic_2d) {
     34     PSInterfaceCore()->ReleaseResource(ctx->graphic_2d);
     35     ctx->graphic_2d = 0;
     36   }
     37   if (ctx->image) {
     38     PSInterfaceCore()->ReleaseResource(ctx->image);
     39     ctx->image = 0;
     40   }
     41   free(ctx);
     42 }
     43 
     44 PP_ImageDataFormat PSContext2DGetNativeImageDataFormat() {
     45   return PSInterfaceImageData()->GetNativeImageDataFormat();
     46 }
     47 
     48 // Update the 2D context if the message is appropriate, returning non-zero
     49 // if the event was consumed.
     50 int PSContext2DHandleEvent(PSContext2D_t* ctx, PSEvent* event) {
     51   switch(event->type) {
     52     case PSE_INSTANCE_DIDCHANGEVIEW: {
     53       struct PP_Rect rect;
     54 
     55       PSInterfaceView()->GetRect(event->as_resource, &rect);
     56       PSInterfaceCore()->ReleaseResource(ctx->graphic_2d);
     57       ctx->bound = 0;
     58       ctx->width = rect.size.width;
     59       ctx->height = rect.size.height;
     60 
     61       // Create an opaque graphic context of the specified size.
     62       ctx->graphic_2d =
     63           PSInterfaceGraphics2D()->Create(PSGetInstanceId(), &rect.size,
     64                                           PP_TRUE);
     65 
     66       // Bind the context to so that draws will be visible.
     67       if (ctx->graphic_2d) {
     68         ctx->bound =
     69             PSInterfaceInstance()->BindGraphics(PSGetInstanceId(),
     70                                                 ctx->graphic_2d);
     71       }
     72 
     73       // Typically this resource would not be allocated yet, but just in case
     74       // throw it away, to force a new allocation when GetBuffer is called.
     75       if (ctx->image) {
     76         PSInterfaceCore()->ReleaseResource(ctx->image);
     77         ctx->image = 0;
     78       }
     79 
     80       return 1;
     81     }
     82     default: break;
     83   }
     84 
     85   return 0;
     86 }
     87 
     88 
     89 // Allocates (if needed) a new image context which will be swapped in when
     90 // drawing is complete.  PSContextGetBuffer and PSContext2DSwapBuffer
     91 // implemented the suggested image/graphic_2d use specified in the
     92 // ppb_graphics_2d header.
     93 int PSContext2DGetBuffer(PSContext2D_t* ctx) {
     94   if (!ctx->bound) return 0;
     95 
     96   // Check if we are already holding an image
     97   if (ctx->image) return 1;
     98 
     99   PP_Size size;
    100   size.width = ctx->width;
    101   size.height = ctx->height;
    102 
    103   // Allocate a new image resource with the specified size and format, but
    104   // do not ZERO out the buffer first since we will fill it.
    105   PP_Resource image =
    106       PSInterfaceImageData()->Create(PSGetInstanceId(), ctx->format, &size,
    107                                      PP_FALSE);
    108 
    109   if (0 == image) {
    110     PSInstance::GetInstance()->Error("Unable to create 2D image.\n");
    111     return 0;
    112   }
    113 
    114   // Get the stride
    115   struct PP_ImageDataDesc desc;
    116   PSInterfaceImageData()->Describe(image, &desc);
    117 
    118   ctx->image = image;
    119   ctx->data = static_cast<uint32_t*>(PSInterfaceImageData()->Map(image));
    120   ctx->stride = desc.stride;
    121   return 1;
    122 }
    123 
    124 int PSContext2DSwapBuffer(PSContext2D_t* ctx) {
    125   if (ctx->bound && ctx->image) {
    126     PSInterfaceImageData()->Unmap(ctx->image);
    127     PSInterfaceGraphics2D()->ReplaceContents(ctx->graphic_2d, ctx->image);
    128     PSInterfaceGraphics2D()->Flush(ctx->graphic_2d, PP_BlockUntilComplete());
    129     PSInterfaceCore()->ReleaseResource(ctx->image);
    130 
    131     ctx->image = 0;
    132     ctx->stride = 0;
    133     ctx->data = NULL;
    134     return 1;
    135   }
    136   return 0;
    137 }
    138 
    139