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