1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/c/pp_errors.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/core.h"
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/graphics_3d.h"
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/graphics_3d_client.h"
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/input_event.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/instance.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/module.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/cpp/rect.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/examples/gles2_spinning_cube/spinning_cube.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ppapi/utility/completion_callback_factory.h"
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use assert as a poor-man's CHECK, even in non-debug mode.
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Since <assert.h> redefines assert on every inclusion (it doesn't use
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// include-guards), make sure this is the last file #include'd in this file.
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#undef NDEBUG
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <assert.h>
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace {
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DemoInstance : public pp::Instance, public pp::Graphics3DClient {
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DemoInstance(PP_Instance instance);
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~DemoInstance();
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // pp::Instance implementation (see PPP_Instance).
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void DidChangeView(const pp::Rect& position,
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             const pp::Rect& clip);
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual bool HandleInputEvent(const pp::InputEvent& event) {
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // TODO(yzshen): Handle input events.
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return true;
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // pp::Graphics3DClient implementation.
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void Graphics3DContextLost();
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // GL-related functions.
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void InitGL(int32_t result);
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void Paint(int32_t result);
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pp::Size plugin_size_;
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pp::CompletionCallbackFactory<DemoInstance> callback_factory_;
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Owned data.
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pp::Graphics3D* context_;
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SpinningCube cube_;
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
56effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDemoInstance::DemoInstance(PP_Instance instance)
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : pp::Instance(instance),
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      pp::Graphics3DClient(this),
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      callback_factory_(this),
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      context_(NULL) {}
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
62effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDemoInstance::~DemoInstance() {
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  assert(glTerminatePPAPI());
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  delete context_;
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool DemoInstance::Init(uint32_t /*argc*/,
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                        const char* /*argn*/[],
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                        const char* /*argv*/[]) {
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return !!glInitializePPAPI(pp::Module::Get()->get_browser_interface());
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DemoInstance::DidChangeView(
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const pp::Rect& position, const pp::Rect& /*clip*/) {
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (position.width() == 0 || position.height() == 0)
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  plugin_size_ = position.size();
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Initialize graphics.
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  InitGL(0);
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DemoInstance::Graphics3DContextLost() {
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  delete context_;
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  context_ = NULL;
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pp::CompletionCallback cb = callback_factory_.NewCallback(
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      &DemoInstance::InitGL);
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pp::Module::Get()->core()->CallOnMainThread(0, cb, 0);
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DemoInstance::InitGL(int32_t /*result*/) {
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  assert(plugin_size_.width() && plugin_size_.height());
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (context_) {
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->ResizeBuffers(plugin_size_.width(), plugin_size_.height());
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int32_t context_attributes[] = {
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_SAMPLES, 0,
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(),
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(),
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PP_GRAPHICS3DATTRIB_NONE,
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  context_ = new pp::Graphics3D(this, context_attributes);
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  assert(!context_->is_null());
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  assert(BindGraphics(*context_));
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  glSetCurrentContextPPAPI(context_->pp_resource());
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  cube_.Init(plugin_size_.width(), plugin_size_.height());
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Paint(PP_OK);
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DemoInstance::Paint(int32_t result) {
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (result != PP_OK || !context_)
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  cube_.UpdateForTimeDelta(0.02f);
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  cube_.Draw();
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  context_->SwapBuffers(callback_factory_.NewCallback(&DemoInstance::Paint));
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This object is the global object representing this plugin library as long
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// as it is loaded.
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DemoModule : public pp::Module {
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DemoModule() : Module() {}
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~DemoModule() {}
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual pp::Instance* CreateInstance(PP_Instance instance) {
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return new DemoInstance(instance);
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // anonymous namespace
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace pp {
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Factory function for your specialization of the Module object.
147effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochModule* CreateModule() {
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return new DemoModule();
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace pp
151