Home | History | Annotate | Download | only in 2d
      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