Home | History | Annotate | Download | only in extra_data
      1 // Copyright 2014 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 
      6 // This plugin is intended to be used in a telemetry test for tracing touch
      7 // input latency. It is a simple touch drawing app, that for each touch move
      8 // event, it draws a square with fix size.
      9 // When the plugin instance is initialized, we call
     10 // InputEventPrivate::StartTrackingLatency to enable latency tracking.
     11 // And for each touch move event, we call
     12 // InputEventPrivate::TraceInputLatency(true) to indicate the touch event
     13 // causes rendering effect and its input latency should be tracked.
     14 // The plugin is built as a pexe and bundled with a telemetry test page.
     15 // For how to build the pexe, see the accompanying README file.
     16 
     17 #include <algorithm>
     18 
     19 #include "ppapi/c/pp_input_event.h"
     20 #include "ppapi/cpp/graphics_2d.h"
     21 #include "ppapi/cpp/image_data.h"
     22 #include "ppapi/cpp/input_event.h"
     23 #include "ppapi/cpp/instance.h"
     24 #include "ppapi/cpp/module.h"
     25 #include "ppapi/cpp/private/input_event_private.h"
     26 #include "ppapi/cpp/size.h"
     27 #include "ppapi/cpp/view.h"
     28 #include "ppapi/utility/graphics/paint_manager.h"
     29 
     30 pp::Rect SquareForTouchPoint(int x, int y) {
     31   return PP_MakeRectFromXYWH(x - 30, y - 30,
     32                              30 * 2 + 1, 30 * 2 + 1);
     33 }
     34 
     35 static void FillRect(pp::ImageData* image,
     36                      int left,
     37                      int top,
     38                      int width,
     39                      int height,
     40                      uint32_t color) {
     41   for (int y = std::max(0, top);
     42        y < std::min(image->size().height() - 1, top + height);
     43        y++) {
     44     for (int x = std::max(0, left);
     45          x < std::min(image->size().width() - 1, left + width);
     46          x++) {
     47       *image->GetAddr32(pp::Point(x, y)) = color;
     48     }
     49   }
     50 }
     51 
     52 class MyInstance : public pp::Instance, public pp::PaintManager::Client {
     53  public:
     54   explicit MyInstance(PP_Instance instance)
     55       : pp::Instance(instance),
     56         paint_manager_() {
     57     paint_manager_.Initialize(this, this, false);
     58     RequestInputEvents(PP_INPUTEVENT_CLASS_TOUCH);
     59     pp::InputEventPrivate::StartTrackingLatency(pp::InstanceHandle(instance));
     60   }
     61 
     62   virtual bool HandleInputEvent(const pp::InputEvent& event) {
     63     switch (event.GetType()) {
     64       case PP_INPUTEVENT_TYPE_TOUCHSTART:
     65       case PP_INPUTEVENT_TYPE_TOUCHEND:
     66       case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
     67         pp::InputEventPrivate private_event(event);
     68         private_event.TraceInputLatency(false);
     69         return true;
     70       }
     71 
     72       case PP_INPUTEVENT_TYPE_TOUCHMOVE: {
     73         pp::TouchInputEvent touch(event);
     74         uint32_t count = touch.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
     75         if (count > 0) {
     76           pp::TouchPoint point = touch.GetTouchByIndex(
     77               PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, 0);
     78           UpdateSquareTouch(static_cast<int>(point.position().x()),
     79                             static_cast<int>(point.position().y()));
     80           pp::InputEventPrivate private_event(event);
     81           private_event.TraceInputLatency(true);
     82         } else {
     83           pp::InputEventPrivate private_event(event);
     84           private_event.TraceInputLatency(false);
     85         }
     86         return true;
     87       }
     88       default:
     89         return false;
     90     }
     91   }
     92 
     93   virtual void DidChangeView(const pp::View& view) {
     94     paint_manager_.SetSize(view.GetRect().size());
     95   }
     96 
     97   // PaintManager::Client implementation.
     98   virtual bool OnPaint(pp::Graphics2D& graphics_2d,
     99                        const std::vector<pp::Rect>& paint_rects,
    100                        const pp::Rect& paint_bounds) {
    101     pp::ImageData updated_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
    102                                 paint_bounds.size(), false);
    103 
    104     for (size_t i = 0; i < paint_rects.size(); i++) {
    105       // Since our image is just the invalid region, we need to offset the
    106       // areas we paint by that much. This is just a light blue background.
    107       FillRect(&updated_image,
    108                paint_rects[i].x(),
    109                paint_rects[i].y(),
    110                paint_rects[i].width(),
    111                paint_rects[i].height(),
    112                0xFF000000);
    113     }
    114 
    115     graphics_2d.PaintImageData(updated_image, paint_bounds.point());
    116     return true;
    117   }
    118 
    119  private:
    120   void UpdateSquareTouch(int x, int y) {
    121     paint_manager_.InvalidateRect(SquareForTouchPoint(x, y));
    122   }
    123 
    124   pp::PaintManager paint_manager_;
    125 };
    126 
    127 class MyModule : public pp::Module {
    128  public:
    129   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    130     return new MyInstance(instance);
    131   }
    132 };
    133 
    134 namespace pp {
    135 
    136 Module* CreateModule() {
    137   return new MyModule();
    138 }
    139 
    140 }  // namespace pp
    141