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 18static const int kSquareSpacing = 98; 19static const int kSquareSize = 5; 20 21static const int kAdvanceXPerFrame = 0; 22static const int kAdvanceYPerFrame = -3; 23 24void 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 35class 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 108class MyModule : public pp::Module { 109 public: 110 virtual pp::Instance* CreateInstance(PP_Instance instance) { 111 return new MyInstance(instance); 112 } 113}; 114 115namespace pp { 116 117// Factory function for your specialization of the Module object. 118Module* CreateModule() { 119 return new MyModule(); 120} 121 122} // namespace pp 123