Home | History | Annotate | Download | only in flash_topmost
      1 // Copyright (c) 2012 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 "ppapi/cpp/graphics_2d.h"
      6 #include "ppapi/cpp/image_data.h"
      7 #include "ppapi/cpp/instance.h"
      8 #include "ppapi/cpp/logging.h"
      9 #include "ppapi/cpp/module.h"
     10 #include "ppapi/cpp/private/flash.h"
     11 #include "ppapi/cpp/rect.h"
     12 #include "ppapi/cpp/size.h"
     13 #include "ppapi/utility/completion_callback_factory.h"
     14 
     15 const int32_t kTimerInterval = 200;
     16 
     17 class MyInstance : public pp::Instance {
     18  public:
     19   explicit MyInstance(PP_Instance instance)
     20       : pp::Instance(instance),
     21         callback_factory_(this),
     22         pending_paint_(false),
     23         waiting_for_flush_completion_(false) {
     24   }
     25   virtual ~MyInstance() {
     26   }
     27 
     28   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
     29     ScheduleNextTimer();
     30     return true;
     31   }
     32 
     33   virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
     34     if (position.size() != size_) {
     35       size_ = position.size();
     36       device_context_ = pp::Graphics2D(this, size_, false);
     37       if (!BindGraphics(device_context_))
     38         return;
     39     }
     40 
     41     Paint();
     42   }
     43 
     44  private:
     45   void ScheduleNextTimer() {
     46     pp::Module::Get()->core()->CallOnMainThread(
     47         kTimerInterval,
     48         callback_factory_.NewCallback(&MyInstance::OnTimer),
     49         0);
     50   }
     51 
     52   void OnTimer(int32_t) {
     53     ScheduleNextTimer();
     54     Paint();
     55   }
     56 
     57   void DidFlush(int32_t result) {
     58     waiting_for_flush_completion_ = false;
     59     if (pending_paint_)
     60       Paint();
     61   }
     62 
     63   void Paint() {
     64     if (waiting_for_flush_completion_) {
     65       pending_paint_ = true;
     66       return;
     67     }
     68 
     69     pending_paint_ = false;
     70 
     71     if (size_.IsEmpty())
     72       return;  // Nothing to do.
     73 
     74     pp::ImageData image = PaintImage(size_);
     75     if (!image.is_null()) {
     76       device_context_.ReplaceContents(&image);
     77       waiting_for_flush_completion_ = true;
     78       device_context_.Flush(
     79           callback_factory_.NewCallback(&MyInstance::DidFlush));
     80     }
     81   }
     82 
     83   pp::ImageData PaintImage(const pp::Size& size) {
     84     pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false);
     85     if (image.is_null())
     86       return image;
     87 
     88     pp::Rect rect(size.width() / 8, size.height() / 4,
     89                   3 * size.width() / 4, size.height() / 2);
     90     uint32_t fill_color = pp::flash::Flash::IsRectTopmost(this, rect) ?
     91         0xff00ff00 : 0xffff0000;
     92 
     93     for (int y = 0; y < size.height(); y++) {
     94       for (int x = 0; x < size.width(); x++)
     95         *image.GetAddr32(pp::Point(x, y)) = fill_color;
     96     }
     97 
     98     for (int x = rect.x(); x < rect.x() + rect.width(); x++) {
     99       *image.GetAddr32(pp::Point(x, rect.y())) = 0xff202020;
    100       *image.GetAddr32(pp::Point(x, rect.y() + rect.height() - 1)) = 0xff202020;
    101     }
    102     for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
    103       *image.GetAddr32(pp::Point(rect.x(), y)) = 0xff202020;
    104       *image.GetAddr32(pp::Point(rect.x() + rect.width() - 1, y)) = 0xff202020;
    105     }
    106 
    107     return image;
    108   }
    109 
    110   pp::CompletionCallbackFactory<MyInstance> callback_factory_;
    111 
    112   // Painting stuff.
    113   pp::Size size_;
    114   pp::Graphics2D device_context_;
    115   bool pending_paint_;
    116   bool waiting_for_flush_completion_;
    117 };
    118 
    119 class MyModule : public pp::Module {
    120  public:
    121   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    122     return new MyInstance(instance);
    123   }
    124 };
    125 
    126 namespace pp {
    127 
    128 // Factory function for your specialization of the Module object.
    129 Module* CreateModule() {
    130   return new MyModule();
    131 }
    132 
    133 }  // namespace pp
    134