1 // Copyright (c) 2011 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 <math.h> 6 7 #include <algorithm> 8 9 #include "ppapi/cpp/graphics_2d.h" 10 #include "ppapi/cpp/image_data.h" 11 #include "ppapi/cpp/instance.h" 12 #include "ppapi/cpp/module.h" 13 #include "ppapi/cpp/rect.h" 14 #include "ppapi/cpp/var.h" 15 #include "ppapi/utility/completion_callback_factory.h" 16 #include "ppapi/utility/graphics/paint_manager.h" 17 18 static const int kSquareSpacing = 98; 19 static const int kSquareSize = 5; 20 21 static const int kAdvanceXPerFrame = 0; 22 static const int kAdvanceYPerFrame = -3; 23 24 void FillRect(pp::ImageData* image, const pp::Rect& rect, uint32_t color) { 25 for (int y = std::max(0, rect.y()); 26 y < std::min(image->size().height(), rect.bottom()); 27 y++) { 28 for (int x = std::max(0, rect.x()); 29 x < std::min(image->size().width(), rect.right()); 30 x++) 31 *image->GetAddr32(pp::Point(x, y)) = color; 32 } 33 } 34 35 class MyInstance : public pp::Instance, public pp::PaintManager::Client { 36 public: 37 MyInstance(PP_Instance instance) 38 : pp::Instance(instance), 39 current_step_(0), 40 kicked_off_(false) { 41 factory_.Initialize(this); 42 paint_manager_.Initialize(this, this, false); 43 } 44 45 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { 46 paint_manager_.SetSize(position.size()); 47 } 48 49 void OnTimer(int32_t) { 50 pp::Module::Get()->core()->CallOnMainThread( 51 16, factory_.NewCallback(&MyInstance::OnTimer), 0); 52 // The scroll and the invalidate will do the same thing in this example, 53 // but the invalidate will cause a large repaint, whereas the scroll will 54 // be faster and cause a smaller repaint. 55 #if 1 56 paint_manager_.ScrollRect(pp::Rect(paint_manager_.graphics().size()), 57 pp::Point(kAdvanceXPerFrame, kAdvanceYPerFrame)); 58 #else 59 paint_manager_.Invalidate(); 60 #endif 61 current_step_++; 62 } 63 64 private: 65 // PaintManager::Client implementation. 66 virtual bool OnPaint(pp::Graphics2D& graphics, 67 const std::vector<pp::Rect>& paint_rects, 68 const pp::Rect& paint_bounds) { 69 if (!kicked_off_) { 70 pp::Module::Get()->core()->CallOnMainThread( 71 16, factory_.NewCallback(&MyInstance::OnTimer), 0); 72 kicked_off_ = true; 73 } 74 75 // Paint the background. 76 pp::ImageData updated_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 77 paint_bounds.size(), false); 78 FillRect(&updated_image, pp::Rect(updated_image.size()), 0xFF8888FF); 79 80 int x_origin = current_step_ * kAdvanceXPerFrame; 81 int y_origin = current_step_ * kAdvanceYPerFrame; 82 83 int x_offset = x_origin % kSquareSpacing; 84 int y_offset = y_origin % kSquareSpacing; 85 86 for (int ys = 0; ys < graphics.size().height() / kSquareSpacing + 2; ys++) { 87 for (int xs = 0; xs < graphics.size().width() / kSquareSpacing + 2; 88 xs++) { 89 int x = xs * kSquareSpacing + x_offset - paint_bounds.x(); 90 int y = ys * kSquareSpacing + y_offset - paint_bounds.y(); 91 FillRect(&updated_image, pp::Rect(x, y, kSquareSize, kSquareSize), 92 0xFF000000); 93 } 94 } 95 graphics.PaintImageData(updated_image, paint_bounds.point()); 96 return true; 97 } 98 99 pp::CompletionCallbackFactory<MyInstance> factory_; 100 101 pp::PaintManager paint_manager_; 102 103 int current_step_; 104 105 bool kicked_off_; 106 }; 107 108 class MyModule : public pp::Module { 109 public: 110 virtual pp::Instance* CreateInstance(PP_Instance instance) { 111 return new MyInstance(instance); 112 } 113 }; 114 115 namespace pp { 116 117 // Factory function for your specialization of the Module object. 118 Module* CreateModule() { 119 return new MyModule(); 120 } 121 122 } // namespace pp 123