| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 <stdio.h> | |
| 6 | |
| 7 #include "GLES2/gl2.h" | |
| 8 | |
| 9 #include "ppapi/cpp/graphics_3d.h" | |
| 10 #include "ppapi/cpp/size.h" | |
| 11 #include "ppapi/gles2/gl2ext_ppapi.h" | |
| 12 #include "ppapi/utility/completion_callback_factory.h" | |
| 13 | |
| 14 #include "ppapi_main/ppapi_instance.h" | |
| 15 #include "ppapi_main/ppapi_instance3d.h" | |
| 16 #include "ppapi_main/ppapi_main.h" | |
| 17 | |
| 18 | |
| 19 void* PPAPI_CreateInstance3D(PP_Instance inst, const char *args[]) { | |
| 20 return static_cast<void*>(new PPAPIInstance3D(inst, args)); | |
| 21 } | |
| 22 | |
| 23 | |
| 24 int32_t *PPAPIGet3DAttribs(uint32_t width, uint32_t height) { | |
| 25 static int32_t attribs[] = { | |
| 26 PP_GRAPHICS3DATTRIB_WIDTH, 0, | |
| 27 PP_GRAPHICS3DATTRIB_HEIGHT, 0, | |
| 28 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, | |
| 29 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, | |
| 30 PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8, | |
| 31 PP_GRAPHICS3DATTRIB_SAMPLES, 0, | |
| 32 PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, | |
| 33 PP_GRAPHICS3DATTRIB_NONE | |
| 34 }; | |
| 35 | |
| 36 attribs[1] = width; | |
| 37 attribs[3] = height; | |
| 38 | |
| 39 printf("Building attribs for %dx%d.\n", width, height); | |
| 40 return attribs; | |
| 41 } | |
| 42 | |
| 43 void PPAPIBuildContext(uint32_t width, uint32_t height) { | |
| 44 glViewport(0, 0, width, height); | |
| 45 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
| 46 printf("Built Context %d, %d.\n", width, height); | |
| 47 } | |
| 48 | |
| 49 | |
| 50 PPAPIInstance3D* PPAPIInstance3D::GetInstance3D() { | |
| 51 return static_cast<PPAPIInstance3D*>(PPAPI_GetInstanceObject()); | |
| 52 } | |
| 53 | |
| 54 void PPAPIInstance3D::Flushed(int result) { | |
| 55 if (result != 0) { | |
| 56 printf("Swapped result=%d.\n", result); | |
| 57 } | |
| 58 | |
| 59 if (is_context_bound_) { | |
| 60 Render(device_context_.pp_resource(), size_.width(), size_.height()); | |
| 61 | |
| 62 int result; | |
| 63 result = device_context_.SwapBuffers(callback_factory_.NewCallback( | |
| 64 &PPAPIInstance::Flushed)); | |
| 65 if (result == PP_OK_COMPLETIONPENDING) return; | |
| 66 printf("Failed swap with %d.\n", result); | |
| 67 } | |
| 68 | |
| 69 // Failed to draw, so add a callback for the future. This could | |
| 70 // an application choice or the browser dealing with an event such as | |
| 71 // fullscreen toggle. We add a delay of 100ms (to prevent burnning CPU | |
| 72 // in cases where the context will not be available for a while. | |
| 73 pp::MessageLoop::GetCurrent().PostWork(callback_factory_.NewCallback( | |
| 74 &PPAPIInstance::Flushed), 100); | |
| 75 } | |
| 76 | |
| 77 void PPAPIInstance3D::BuildContext(int32_t result, const pp::Size& new_size) { | |
| 78 printf("Building context.\n"); | |
| 79 | |
| 80 // If already bound, try to resize to avoid the need to rebuild the context. | |
| 81 if (is_context_bound_) { | |
| 82 // If the size is correct, then just skip this request. | |
| 83 if (new_size == size_) { | |
| 84 printf("Skipped building context, same size as bound.\n"); | |
| 85 return; | |
| 86 } | |
| 87 int err = device_context_.ResizeBuffers(new_size.width(), | |
| 88 new_size.height()); | |
| 89 | |
| 90 // Resized the context, we are done | |
| 91 if (err == PP_OK) { | |
| 92 size_ = new_size; | |
| 93 fprintf(stderr, "Resized context from %dx%d to %dx%d", | |
| 94 size_.width(), size_.height(), new_size.width(), | |
| 95 new_size.height()); | |
| 96 PPAPIBuildContext(size_.width(), size_.height()); | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 // Failed to resize, fall through and start from scratch | |
| 101 fprintf(stderr, "Failed to resize buffer from %dx%d to %dx%d", | |
| 102 size_.width(), size_.height(), new_size.width(), new_size.height()); | |
| 103 | |
| 104 is_context_bound_ = false; | |
| 105 } | |
| 106 | |
| 107 printf("Calling create context....\n"); | |
| 108 size_ = new_size; | |
| 109 device_context_ = pp::Graphics3D(this, PPAPIGet3DAttribs(size_.width(), | |
| 110 size_.height())); | |
| 111 printf("Got Context!\n"); | |
| 112 is_context_bound_ = BindGraphics(device_context_); | |
| 113 printf("Context is bound=%d\n", is_context_bound_); | |
| 114 | |
| 115 // Set the context regardless to make sure we have a valid one | |
| 116 glSetCurrentContextPPAPI(device_context_.pp_resource()); | |
| 117 if (is_context_bound_) { | |
| 118 PPAPIBuildContext(size_.width(), size_.height()); | |
| 119 device_context_.SwapBuffers(callback_factory_.NewCallback( | |
| 120 &PPAPIInstance::Flushed)); | |
| 121 } else { | |
| 122 fprintf(stderr, "Failed to bind context for %dx%d.\n", size_.width(), | |
| 123 size_.height()); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 // The default implementation calls the 'C' render function. | |
| 128 void PPAPIInstance3D::Render(PP_Resource ctx, uint32_t width, | |
| 129 uint32_t height) { | |
| 130 PPAPIRender(ctx, width, height); | |
| 131 } | |
| 132 | |
| 133 PPAPIInstance3D::PPAPIInstance3D(PP_Instance instance, const char *args[]) | |
| 134 : PPAPIInstance(instance, args) { | |
| 135 glInitializePPAPI(pp::Module::Get()->get_browser_interface()); | |
| 136 } | |
| 137 | |
| 138 | |
| 139 PPAPIInstance3D::~PPAPIInstance3D() { | |
| 140 if (is_context_bound_) { | |
| 141 is_context_bound_ = false; | |
| 142 // Cleanup code? | |
| 143 } | |
| 144 } | |
| OLD | NEW |