Fix osmand build
This commit is contained in:
parent
025274008f
commit
37ba9dcca0
8 changed files with 393 additions and 178 deletions
|
@ -1,6 +1,7 @@
|
|||
ifeq ($(ARCH),)
|
||||
ifndef $(ARCH)
|
||||
ARCH := x86
|
||||
endif
|
||||
|
||||
############################################
|
||||
############# NACL ### TARGET
|
||||
ifeq ($(TARGET),nacl)
|
||||
|
@ -26,10 +27,10 @@ CC:=$(TC_PATH)/bin/i686-nacl-gcc
|
|||
STATICLIB_EXT := a
|
||||
DYNAMICLIB_EXT := nexe
|
||||
LIBRARY_PREFIX := lib
|
||||
LDFLAGS := -lppapi
|
||||
LDFLAGS := -lppapi_cpp -lppapi
|
||||
GLOBAL_INCLUDES=-I../zlib/zlib_library -I$(TC_PATH)/i686-nacl/usr/include
|
||||
RT_NOT_SUPPORTED :=
|
||||
ZLIB_BUILD :=
|
||||
RT_NOT_SUPPORTED := defined
|
||||
ZLIB_BUILD := defined
|
||||
|
||||
ifeq ($(ARCH),x86)
|
||||
CFLAGS += -m32
|
||||
|
@ -83,7 +84,9 @@ RANLIB := i586-mingw32msvc-ranlib
|
|||
WINDRES := i586-mingw32msvc-windres
|
||||
AR := i586-mingw32msvc-ar
|
||||
GLOBAL_INCLUDES := -I../pthread/pthreads_library -I../zlib/zlib_library
|
||||
RT_NOT_SUPPORTED := 1
|
||||
RT_NOT_SUPPORTED := defined
|
||||
ZLIB_BUILD := defined
|
||||
PTHREAD_BUILD := defined
|
||||
COMMONFLAGS := -D_Windows -DXMD_H -DHAVE_BOOLEAN -DRT_NOT_SUPPORTED
|
||||
CPP_FLAGS := $(COMMONFLAGS)
|
||||
CFLAGS := -D_JNI_IMPLEMENTATION $(COMMONFLAGS)
|
||||
|
|
|
@ -11,6 +11,8 @@ LOCAL_MODULE := osmand_neon
|
|||
LOCAL_ARM_NEON := true
|
||||
endif
|
||||
|
||||
LOCAL_SRC_FILES += src/java_wrap.cpp
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
-DGOOGLE_PROTOBUF_NO_RTTI \
|
||||
-DANDROID_BUILD \
|
||||
|
|
3
Osmand-kernel/osmand/nacl/.gitignore
vendored
3
Osmand-kernel/osmand/nacl/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
*.nexe
|
||||
osmand-*.nexe
|
||||
|
||||
|
|
|
@ -69,11 +69,19 @@
|
|||
appendToEventLog('abort');
|
||||
}
|
||||
|
||||
// When the NaCl module has loaded indicate success.
|
||||
var piGenerator = null;
|
||||
var paintInterval = null;
|
||||
|
||||
// Start up the paint timer when the NaCl module has loaded.
|
||||
function moduleDidLoad() {
|
||||
loadProgressModule = document.getElementById('load_progress');
|
||||
appendToEventLog('load');
|
||||
updateStatus('SUCCESS');
|
||||
piGenerator = document.getElementById('load_progress');
|
||||
paintInterval = setInterval('load_progress.postMessage("paint")', 50);
|
||||
}
|
||||
function pageDidUnload() {
|
||||
clearInterval(paintInterval);
|
||||
}
|
||||
|
||||
// Handler that gets called when the NaCl module loading has completed.
|
||||
|
@ -94,7 +102,8 @@
|
|||
|
||||
// Handle a message coming from the NaCl module.
|
||||
function handleMessage(message_event) {
|
||||
alert(message_event.data);
|
||||
// alert(message_event.data);
|
||||
//document.form.pi.value = message_event.data;
|
||||
}
|
||||
|
||||
// Set the global status message. Updates the 'status_field' element with
|
||||
|
@ -195,7 +204,7 @@
|
|||
-->
|
||||
<embed name="nacl_module"
|
||||
id="load_progress"
|
||||
width=0 height=0
|
||||
width=500 height=500
|
||||
src="osmand.nmf"
|
||||
type="application/x-nacl" />
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,182 +1,266 @@
|
|||
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/** @file hello_world.c
|
||||
* This example demonstrates loading, running and scripting a very simple
|
||||
* NaCl module.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "ppapi/cpp/completion_callback.h"
|
||||
#include "ppapi/cpp/var.h"
|
||||
#include <ppapi/cpp/module.h>
|
||||
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/c/pp_module.h"
|
||||
#include "ppapi/c/pp_var.h"
|
||||
#include "ppapi/c/ppb.h"
|
||||
#include "ppapi/c/ppb_instance.h"
|
||||
#include "ppapi/c/ppb_messaging.h"
|
||||
#include "ppapi/c/ppb_var.h"
|
||||
#include "ppapi/c/ppp.h"
|
||||
#include "ppapi/c/ppp_instance.h"
|
||||
#include "ppapi/c/ppp_messaging.h"
|
||||
#include "osmand_nacl.h"
|
||||
|
||||
static PPB_Messaging* ppb_messaging_interface = NULL;
|
||||
static PPB_Var* ppb_var_interface = NULL;
|
||||
namespace {
|
||||
const int kPthreadMutexSuccess = 0;
|
||||
const char* const kPaintMethodId = "paint";
|
||||
const double kInvalidPiValue = -1.0;
|
||||
const int kMaxPointCount = 1000000000; // The total number of points to draw.
|
||||
const uint32_t kOpaqueColorMask = 0xff000000; // Opaque pixels.
|
||||
const uint32_t kRedMask = 0xff0000;
|
||||
const uint32_t kBlueMask = 0xff;
|
||||
const uint32_t kRedShift = 16;
|
||||
const uint32_t kBlueShift = 0;
|
||||
|
||||
// This is called by the browser when the 2D context has been flushed to the
|
||||
// browser window.
|
||||
void FlushCallback(void* data, int32_t result) {
|
||||
static_cast<osmand::PiGenerator*>(data)->set_flush_pending(false);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* Creates new string PP_Var from C string. The resulting object will be a
|
||||
* refcounted string object. It will be AddRef()ed for the caller. When the
|
||||
* caller is done with it, it should be Release()d.
|
||||
* @param[in] str C string to be converted to PP_Var
|
||||
* @return PP_Var containing string.
|
||||
*/
|
||||
static struct PP_Var CStrToVar(const char* str) {
|
||||
if (ppb_var_interface != NULL) {
|
||||
return ppb_var_interface->VarFromUtf8(str, strlen(str));
|
||||
namespace osmand {
|
||||
|
||||
// A small helper RAII class that implementes a scoped pthread_mutex lock.
|
||||
class ScopedMutexLock {
|
||||
public:
|
||||
explicit ScopedMutexLock(pthread_mutex_t* mutex) : mutex_(mutex) {
|
||||
if (pthread_mutex_lock(mutex_) != kPthreadMutexSuccess) {
|
||||
mutex_ = NULL;
|
||||
}
|
||||
}
|
||||
return PP_MakeUndefined();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the NaCl module is instantiated on the web page. The identifier
|
||||
* of the new instance will be passed in as the first argument (this value is
|
||||
* generated by the browser and is an opaque handle). This is called for each
|
||||
* instantiation of the NaCl module, which is each time the <embed> tag for
|
||||
* this module is encountered.
|
||||
*
|
||||
* If this function reports a failure (by returning @a PP_FALSE), the NaCl
|
||||
* module will be deleted and DidDestroy will be called.
|
||||
* @param[in] instance The identifier of the new instance representing this
|
||||
* NaCl module.
|
||||
* @param[in] argc The number of arguments contained in @a argn and @a argv.
|
||||
* @param[in] argn An array of argument names. These argument names are
|
||||
* supplied in the <embed> tag, for example:
|
||||
* <embed id="nacl_module" dimensions="2">
|
||||
* will produce two arguments, one named "id" and one named "dimensions".
|
||||
* @param[in] argv An array of argument values. These are the values of the
|
||||
* arguments listed in the <embed> tag. In the above example, there will
|
||||
* be two elements in this array, "nacl_module" and "2". The indices of
|
||||
* these values match the indices of the corresponding names in @a argn.
|
||||
* @return @a PP_TRUE on success.
|
||||
*/
|
||||
static PP_Bool Instance_DidCreate(PP_Instance instance,
|
||||
uint32_t argc,
|
||||
const char* argn[],
|
||||
const char* argv[]) {
|
||||
ppb_messaging_interface->PostMessage(instance,
|
||||
CStrToVar("Osmand application"));
|
||||
return PP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the NaCl module is destroyed. This will always be called,
|
||||
* even if DidCreate returned failure. This routine should deallocate any data
|
||||
* associated with the instance.
|
||||
* @param[in] instance The identifier of the instance representing this NaCl
|
||||
* module.
|
||||
*/
|
||||
static void Instance_DidDestroy(PP_Instance instance) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the position, the size, or the clip rect of the element in the
|
||||
* browser that corresponds to this NaCl module has changed.
|
||||
* @param[in] instance The identifier of the instance representing this NaCl
|
||||
* module.
|
||||
* @param[in] position The location on the page of this NaCl module. This is
|
||||
* relative to the top left corner of the viewport, which changes as the
|
||||
* page is scrolled.
|
||||
* @param[in] clip The visible region of the NaCl module. This is relative to
|
||||
* the top left of the plugin's coordinate system (not the page). If the
|
||||
* plugin is invisible, @a clip will be (0, 0, 0, 0).
|
||||
*/
|
||||
static void Instance_DidChangeView(PP_Instance instance,
|
||||
PP_Resource view_resource) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the given NaCl module has gained or lost focus.
|
||||
* Having focus means that keyboard events will be sent to the NaCl module
|
||||
* represented by @a instance. A NaCl module's default condition is that it
|
||||
* will not have focus.
|
||||
*
|
||||
* Note: clicks on NaCl modules will give focus only if you handle the
|
||||
* click event. You signal if you handled it by returning @a true from
|
||||
* HandleInputEvent. Otherwise the browser will bubble the event and give
|
||||
* focus to the element on the page that actually did end up consuming it.
|
||||
* If you're not getting focus, check to make sure you're returning true from
|
||||
* the mouse click in HandleInputEvent.
|
||||
* @param[in] instance The identifier of the instance representing this NaCl
|
||||
* module.
|
||||
* @param[in] has_focus Indicates whether this NaCl module gained or lost
|
||||
* event focus.
|
||||
*/
|
||||
static void Instance_DidChangeFocus(PP_Instance instance,
|
||||
PP_Bool has_focus) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler that gets called after a full-frame module is instantiated based on
|
||||
* registered MIME types. This function is not called on NaCl modules. This
|
||||
* function is essentially a place-holder for the required function pointer in
|
||||
* the PPP_Instance structure.
|
||||
* @param[in] instance The identifier of the instance representing this NaCl
|
||||
* module.
|
||||
* @param[in] url_loader A PP_Resource an open PPB_URLLoader instance.
|
||||
* @return PP_FALSE.
|
||||
*/
|
||||
static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,
|
||||
PP_Resource url_loader) {
|
||||
/* NaCl modules do not need to handle the document load function. */
|
||||
return PP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Entry points for the module.
|
||||
* Initialize needed interfaces: PPB_Core, PPB_Messaging and PPB_Var.
|
||||
* @param[in] a_module_id module ID
|
||||
* @param[in] get_browser pointer to PPB_GetInterface
|
||||
* @return PP_OK on success, any other value on failure.
|
||||
*/
|
||||
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id,
|
||||
PPB_GetInterface get_browser) {
|
||||
ppb_messaging_interface =
|
||||
(PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
|
||||
ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an interface pointer for the interface of the given name, or NULL
|
||||
* if the interface is not supported.
|
||||
* @param[in] interface_name name of the interface
|
||||
* @return pointer to the interface
|
||||
*/
|
||||
PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
|
||||
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
|
||||
static PPP_Instance instance_interface = {
|
||||
&Instance_DidCreate,
|
||||
&Instance_DidDestroy,
|
||||
&Instance_DidChangeView,
|
||||
&Instance_DidChangeFocus,
|
||||
&Instance_HandleDocumentLoad,
|
||||
};
|
||||
return &instance_interface;
|
||||
~ScopedMutexLock() {
|
||||
if (mutex_)
|
||||
pthread_mutex_unlock(mutex_);
|
||||
}
|
||||
return NULL;
|
||||
bool is_valid() const {
|
||||
return mutex_ != NULL;
|
||||
}
|
||||
private:
|
||||
pthread_mutex_t* mutex_; // Weak reference.
|
||||
};
|
||||
|
||||
// A small helper RAII class used to acquire and release the pixel lock.
|
||||
class ScopedPixelLock {
|
||||
public:
|
||||
explicit ScopedPixelLock(PiGenerator* image_owner)
|
||||
: image_owner_(image_owner), pixels_(image_owner->LockPixels()) {}
|
||||
|
||||
~ScopedPixelLock() {
|
||||
pixels_ = NULL;
|
||||
image_owner_->UnlockPixels();
|
||||
}
|
||||
|
||||
uint32_t* pixels() const {
|
||||
return pixels_;
|
||||
}
|
||||
private:
|
||||
PiGenerator* image_owner_; // Weak reference.
|
||||
uint32_t* pixels_; // Weak reference.
|
||||
|
||||
ScopedPixelLock(); // Not implemented, do not use.
|
||||
};
|
||||
|
||||
PiGenerator::PiGenerator(PP_Instance instance)
|
||||
: pp::Instance(instance),
|
||||
graphics_2d_context_(NULL),
|
||||
pixel_buffer_(NULL),
|
||||
flush_pending_(false),
|
||||
quit_(false),
|
||||
compute_pi_thread_(0),
|
||||
pi_(0.0) {
|
||||
pthread_mutex_init(&pixel_buffer_mutex_, NULL);
|
||||
}
|
||||
|
||||
PiGenerator::~PiGenerator() {
|
||||
quit_ = true;
|
||||
if (compute_pi_thread_) {
|
||||
pthread_join(compute_pi_thread_, NULL);
|
||||
}
|
||||
DestroyContext();
|
||||
// The ComputePi() thread should be gone by now, so there is no need to
|
||||
// acquire the mutex for |pixel_buffer_|.
|
||||
delete pixel_buffer_;
|
||||
pthread_mutex_destroy(&pixel_buffer_mutex_);
|
||||
}
|
||||
|
||||
void PiGenerator::DidChangeView(const pp::Rect& position,
|
||||
const pp::Rect& clip) {
|
||||
if (position.size().width() == width() &&
|
||||
position.size().height() == height())
|
||||
return; // Size didn't change, no need to update anything.
|
||||
|
||||
// Create a new device context with the new size.
|
||||
DestroyContext();
|
||||
CreateContext(position.size());
|
||||
// Delete the old pixel buffer and create a new one.
|
||||
ScopedMutexLock scoped_mutex(&pixel_buffer_mutex_);
|
||||
delete pixel_buffer_;
|
||||
pixel_buffer_ = NULL;
|
||||
if (graphics_2d_context_ != NULL) {
|
||||
pixel_buffer_ = new pp::ImageData(this,
|
||||
PP_IMAGEDATAFORMAT_BGRA_PREMUL,
|
||||
graphics_2d_context_->size(),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
bool PiGenerator::Init(uint32_t argc, const char* argn[], const char* argv[]) {
|
||||
pthread_create(&compute_pi_thread_, NULL, ComputePi, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t* PiGenerator::LockPixels() {
|
||||
void* pixels = NULL;
|
||||
// Do not use a ScopedMutexLock here, since the lock needs to be held until
|
||||
// the matching UnlockPixels() call.
|
||||
if (pthread_mutex_lock(&pixel_buffer_mutex_) == kPthreadMutexSuccess) {
|
||||
if (pixel_buffer_ != NULL && !pixel_buffer_->is_null()) {
|
||||
pixels = pixel_buffer_->data();
|
||||
}
|
||||
}
|
||||
return reinterpret_cast<uint32_t*>(pixels);
|
||||
}
|
||||
|
||||
void PiGenerator::HandleMessage(const pp::Var& var_message) {
|
||||
if (!var_message.is_string()) {
|
||||
PostMessage(pp::Var(kInvalidPiValue));
|
||||
}
|
||||
std::string message = var_message.AsString();
|
||||
if (message == kPaintMethodId) {
|
||||
Paint();
|
||||
} else {
|
||||
PostMessage(pp::Var(kInvalidPiValue));
|
||||
}
|
||||
}
|
||||
|
||||
void PiGenerator::UnlockPixels() const {
|
||||
pthread_mutex_unlock(&pixel_buffer_mutex_);
|
||||
}
|
||||
|
||||
void PiGenerator::Paint() {
|
||||
ScopedMutexLock scoped_mutex(&pixel_buffer_mutex_);
|
||||
if (!scoped_mutex.is_valid()) {
|
||||
return;
|
||||
}
|
||||
FlushPixelBuffer();
|
||||
// Post the current estimate of Pi back to the browser.
|
||||
pp::Var pi_estimate(pi());
|
||||
// Paint() is called on the main thread, so no need for CallOnMainThread()
|
||||
// here. It's OK to just post the message.
|
||||
PostMessage(pi_estimate);
|
||||
}
|
||||
|
||||
void PiGenerator::CreateContext(const pp::Size& size) {
|
||||
ScopedMutexLock scoped_mutex(&pixel_buffer_mutex_);
|
||||
if (!scoped_mutex.is_valid()) {
|
||||
return;
|
||||
}
|
||||
if (IsContextValid())
|
||||
return;
|
||||
graphics_2d_context_ = new pp::Graphics2D(this, size, false);
|
||||
if (!BindGraphics(*graphics_2d_context_)) {
|
||||
printf("Couldn't bind the device context\n");
|
||||
}
|
||||
}
|
||||
|
||||
void PiGenerator::DestroyContext() {
|
||||
ScopedMutexLock scoped_mutex(&pixel_buffer_mutex_);
|
||||
if (!scoped_mutex.is_valid()) {
|
||||
return;
|
||||
}
|
||||
if (!IsContextValid())
|
||||
return;
|
||||
delete graphics_2d_context_;
|
||||
graphics_2d_context_ = NULL;
|
||||
}
|
||||
|
||||
void PiGenerator::FlushPixelBuffer() {
|
||||
if (!IsContextValid())
|
||||
return;
|
||||
// Note that the pixel lock is held while the buffer is copied into the
|
||||
// device context and then flushed.
|
||||
graphics_2d_context_->PaintImageData(*pixel_buffer_, pp::Point());
|
||||
if (flush_pending())
|
||||
return;
|
||||
set_flush_pending(true);
|
||||
graphics_2d_context_->Flush(pp::CompletionCallback(&FlushCallback, this));
|
||||
}
|
||||
|
||||
void* PiGenerator::ComputePi(void* param) {
|
||||
int count = 0; // The number of points put inside the inscribed quadrant.
|
||||
unsigned int seed = 1;
|
||||
PiGenerator* pi_generator = static_cast<PiGenerator*>(param);
|
||||
srand(seed);
|
||||
for (int i = 1; i <= kMaxPointCount && !pi_generator->quit(); ++i) {
|
||||
ScopedPixelLock scoped_pixel_lock(pi_generator);
|
||||
uint32_t* pixel_bits = scoped_pixel_lock.pixels();
|
||||
if (pixel_bits == NULL) {
|
||||
// Note that if the pixel buffer never gets initialized, this won't ever
|
||||
// paint anything. Which is probably the right thing to do. Also, this
|
||||
// clause means that the image will not get the very first few Pi dots,
|
||||
// since it's possible that this thread starts before the pixel buffer is
|
||||
// initialized.
|
||||
continue;
|
||||
}
|
||||
double x = static_cast<double>(rand_r(&seed)) / RAND_MAX;
|
||||
double y = static_cast<double>(rand_r(&seed)) / RAND_MAX;
|
||||
double distance = sqrt(x * x + y * y);
|
||||
int px = x * pi_generator->width();
|
||||
int py = (1.0 - y) * pi_generator->height();
|
||||
uint32_t color = pixel_bits[pi_generator->width() * py + px];
|
||||
if (distance < 1.0) {
|
||||
// Set color to blue.
|
||||
++count;
|
||||
pi_generator->pi_ = 4.0 * count / i;
|
||||
color += 4 << kBlueShift;
|
||||
color &= kBlueMask;
|
||||
} else {
|
||||
// Set color to red.
|
||||
color += 4 << kRedShift;
|
||||
color &= kRedMask;
|
||||
}
|
||||
pixel_bits[pi_generator->width() * py + px] = color | kOpaqueColorMask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called before the plugin module is unloaded.
|
||||
*/
|
||||
PP_EXPORT void PPP_ShutdownModule() {
|
||||
// The Module class. The browser calls the CreateInstance() method to create
|
||||
// an instance of your NaCl module on the web page. The browser creates a new
|
||||
// instance for each <embed> tag with type="application/x-nacl".
|
||||
class OsmandModule : public pp::Module {
|
||||
public:
|
||||
OsmandModule() : pp::Module() {}
|
||||
virtual ~OsmandModule() {}
|
||||
|
||||
// Create and return a PiGeneratorInstance object.
|
||||
virtual pp::Instance* CreateInstance(PP_Instance instance) {
|
||||
return new PiGenerator(instance);
|
||||
}
|
||||
};
|
||||
} // namespace osmand
|
||||
|
||||
// Factory function called by the browser when the module is first loaded.
|
||||
// The browser keeps a singleton of this module. It calls the
|
||||
// CreateInstance() method on the object you return to make instances. There
|
||||
// is one instance per <embed> tag on the page. This is the main binding
|
||||
// point for your NaCl module with the browser.
|
||||
namespace pp {
|
||||
Module* CreateModule() {
|
||||
return new osmand::OsmandModule();
|
||||
}
|
||||
} // namespace pp
|
||||
|
|
116
Osmand-kernel/osmand/src/osmand_nacl.h
Normal file
116
Osmand-kernel/osmand/src/osmand_nacl.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef OSMAND_NACL_H_
|
||||
#define OSMAND_NACL_H_
|
||||
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "ppapi/cpp/graphics_2d.h"
|
||||
#include "ppapi/cpp/image_data.h"
|
||||
#include "ppapi/cpp/instance.h"
|
||||
#include "ppapi/cpp/rect.h"
|
||||
#include "ppapi/cpp/size.h"
|
||||
|
||||
namespace osmand {
|
||||
|
||||
// The Instance class. One of these exists for each instance of your NaCl
|
||||
// module on the web page. The browser will ask the Module object to create
|
||||
// a new Instance for each occurrence of the <embed> tag that has these
|
||||
// attributes:
|
||||
// type="application/x-nacl"
|
||||
// nacl="pi_generator.nmf"
|
||||
class PiGenerator : public pp::Instance {
|
||||
public:
|
||||
explicit PiGenerator(PP_Instance instance);
|
||||
virtual ~PiGenerator();
|
||||
|
||||
// Start up the ComputePi() thread.
|
||||
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
|
||||
|
||||
// Update the graphics context to the new size, and regenerate |pixel_buffer_|
|
||||
// to fit the new size as well.
|
||||
virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip);
|
||||
|
||||
// Called by the browser to handle the postMessage() call in Javascript.
|
||||
// The message in this case is expected to contain the string 'paint', and
|
||||
// if so this invokes the Paint() function. If |var_message| is not a string
|
||||
// type, or contains something other than 'paint', this method posts an
|
||||
// invalid value for Pi (-1.0) back to the browser.
|
||||
virtual void HandleMessage(const pp::Var& var_message);
|
||||
|
||||
// Return a pointer to the pixels represented by |pixel_buffer_|. When this
|
||||
// method returns, the underlying |pixel_buffer_| object is locked. This
|
||||
// call must have a matching UnlockPixels() or various threading errors
|
||||
// (e.g. deadlock) will occur.
|
||||
uint32_t* LockPixels();
|
||||
// Release the image lock acquired by LockPixels().
|
||||
void UnlockPixels() const;
|
||||
|
||||
// Flushes its contents of |pixel_buffer_| to the 2D graphics context. The
|
||||
// ComputePi() thread fills in |pixel_buffer_| pixels as it computes Pi.
|
||||
// This method is called by HandleMessage when a message containing 'paint'
|
||||
// is received. Echos the current value of pi as computed by the Monte Carlo
|
||||
// method by posting the value back to the browser.
|
||||
void Paint();
|
||||
|
||||
bool quit() const {
|
||||
return quit_;
|
||||
}
|
||||
|
||||
// |pi_| is computed in the ComputePi() thread.
|
||||
double pi() const {
|
||||
return pi_;
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return pixel_buffer_ ? pixel_buffer_->size().width() : 0;
|
||||
}
|
||||
int height() const {
|
||||
return pixel_buffer_ ? pixel_buffer_->size().height() : 0;
|
||||
}
|
||||
|
||||
// Indicate whether a flush is pending. This can only be called from the
|
||||
// main thread; it is not thread safe.
|
||||
bool flush_pending() const {
|
||||
return flush_pending_;
|
||||
}
|
||||
void set_flush_pending(bool flag) {
|
||||
flush_pending_ = flag;
|
||||
}
|
||||
|
||||
private:
|
||||
// Create and initialize the 2D context used for drawing.
|
||||
void CreateContext(const pp::Size& size);
|
||||
// Destroy the 2D drawing context.
|
||||
void DestroyContext();
|
||||
// Push the pixels to the browser, then attempt to flush the 2D context. If
|
||||
// there is a pending flush on the 2D context, then update the pixels only
|
||||
// and do not flush.
|
||||
void FlushPixelBuffer();
|
||||
|
||||
bool IsContextValid() const {
|
||||
return graphics_2d_context_ != NULL;
|
||||
}
|
||||
|
||||
mutable pthread_mutex_t pixel_buffer_mutex_;
|
||||
pp::Graphics2D* graphics_2d_context_;
|
||||
pp::ImageData* pixel_buffer_;
|
||||
bool flush_pending_;
|
||||
bool quit_;
|
||||
pthread_t compute_pi_thread_;
|
||||
double pi_;
|
||||
|
||||
// ComputePi() estimates Pi using Monte Carlo method and it is executed by a
|
||||
// separate thread created in SetWindow(). ComputePi() puts kMaxPointCount
|
||||
// points inside the square whose length of each side is 1.0, and calculates
|
||||
// the ratio of the number of points put inside the inscribed quadrant divided
|
||||
// by the total number of random points to get Pi/4.
|
||||
static void* ComputePi(void* param);
|
||||
};
|
||||
|
||||
} // namespace osmand
|
||||
|
||||
#endif // OSMAND_NACL_H
|
Loading…
Reference in a new issue