15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <algorithm> 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_2d.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/image_data.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/rect.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/graphics/paint_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSquareSpacing = 98; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSquareSize = 5; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAdvanceXPerFrame = 0; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAdvanceYPerFrame = -3; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillRect(pp::ImageData* image, const pp::Rect& rect, uint32_t color) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = std::max(0, rect.y()); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y < std::min(image->size().height(), rect.bottom()); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y++) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = std::max(0, rect.x()); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x < std::min(image->size().width(), rect.right()); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x++) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *image->GetAddr32(pp::Point(x, y)) = color; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MyInstance : public pp::Instance, public pp::PaintManager::Client { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MyInstance(PP_Instance instance) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pp::Instance(instance), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_step_(0), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kicked_off_(false) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory_.Initialize(this); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_manager_.Initialize(this, this, false); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_manager_.SetSize(position.size()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTimer(int32_t) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->core()->CallOnMainThread( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, factory_.NewCallback(&MyInstance::OnTimer), 0); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The scroll and the invalidate will do the same thing in this example, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but the invalidate will cause a large repaint, whereas the scroll will 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be faster and cause a smaller repaint. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_manager_.ScrollRect(pp::Rect(paint_manager_.graphics().size()), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Point(kAdvanceXPerFrame, kAdvanceYPerFrame)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_manager_.Invalidate(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_step_++; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PaintManager::Client implementation. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnPaint(pp::Graphics2D& graphics, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<pp::Rect>& paint_rects, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& paint_bounds) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!kicked_off_) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->core()->CallOnMainThread( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, factory_.NewCallback(&MyInstance::OnTimer), 0); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kicked_off_ = true; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Paint the background. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData updated_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_bounds.size(), false); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRect(&updated_image, pp::Rect(updated_image.size()), 0xFF8888FF); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x_origin = current_step_ * kAdvanceXPerFrame; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y_origin = current_step_ * kAdvanceYPerFrame; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x_offset = x_origin % kSquareSpacing; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y_offset = y_origin % kSquareSpacing; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int ys = 0; ys < graphics.size().height() / kSquareSpacing + 2; ys++) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int xs = 0; xs < graphics.size().width() / kSquareSpacing + 2; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xs++) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = xs * kSquareSpacing + x_offset - paint_bounds.x(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = ys * kSquareSpacing + y_offset - paint_bounds.y(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRect(&updated_image, pp::Rect(x, y, kSquareSize, kSquareSize), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xFF000000); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics.PaintImageData(updated_image, paint_bounds.point()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallbackFactory<MyInstance> factory_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::PaintManager paint_manager_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int current_step_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool kicked_off_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MyModule : public pp::Module { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual pp::Instance* CreateInstance(PP_Instance instance) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new MyInstance(instance); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Factory function for your specialization of the Module object. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Module* CreateModule() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new MyModule(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace pp 123