| /* 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_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; |
| |
| struct 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) { |
| PSInstanceError("Unable to create 2D image.\n"); |
| return 0; |
| } |
| |
| // Get the stride |
| struct PP_ImageDataDesc desc; |
| PSInterfaceImageData()->Describe(image, &desc); |
| |
| ctx->image = image; |
| ctx->data = (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; |
| } |