summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-19 14:46:05 +0000
committerraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-19 14:46:05 +0000
commit38f428f10f6e3dca2ff875e663f614aa56fc099f (patch)
tree968c95f0c8eb184930f0e9a982020c0285da84e7 /ppapi
parent9e7e4122711c551a3885d1b641dcadbfcf31b241 (diff)
downloadchromium_src-38f428f10f6e3dca2ff875e663f614aa56fc099f.zip
chromium_src-38f428f10f6e3dca2ff875e663f614aa56fc099f.tar.gz
chromium_src-38f428f10f6e3dca2ff875e663f614aa56fc099f.tar.bz2
Hookup RawVarData to SerializedVar
This hooks up the rewritten RawVarData implementation with SerializedVar. It also fixes tests to make sure that shmem ArrayBuffers are actually tested. Previously, no testing of shmem ArrayBuffers was happening because OS_LINUX is never defined in ppapi/tests and none of the other ArrayBuffer test sizes were above the threshhold to invoke that code path. This CL adds a PPB_Testing function to set the threshhold to a lower value, which permits this code path to be taken while still having fast tests. BUG= Review URL: https://chromiumcodereview.appspot.com/14208016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195189 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/api/dev/ppb_testing_dev.idl14
-rw-r--r--ppapi/c/dev/ppb_testing_dev.h32
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c78
-rw-r--r--ppapi/proxy/handle_converter.cc26
-rw-r--r--ppapi/proxy/ppapi_messages.h3
-rw-r--r--ppapi/proxy/ppb_testing_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_testing_proxy.h1
-rw-r--r--ppapi/proxy/raw_var_data.cc35
-rw-r--r--ppapi/proxy/raw_var_data.h15
-rw-r--r--ppapi/proxy/serialized_var.cc273
-rw-r--r--ppapi/proxy/serialized_var.h58
-rw-r--r--ppapi/tests/test_post_message.cc26
12 files changed, 258 insertions, 326 deletions
diff --git a/ppapi/api/dev/ppb_testing_dev.idl b/ppapi/api/dev/ppb_testing_dev.idl
index 6c0b22b..c114db0 100644
--- a/ppapi/api/dev/ppb_testing_dev.idl
+++ b/ppapi/api/dev/ppb_testing_dev.idl
@@ -13,7 +13,8 @@ label Chrome {
M14 = 0.7,
M15 = 0.8,
M17 = 0.9,
- M18 = 0.91
+ M18 = 0.91,
+ M28 = 0.92
};
interface PPB_Testing_Dev {
@@ -127,4 +128,15 @@ interface PPB_Testing_Dev {
[version=0.91]
uint32_t GetLiveVars([size_as=array_size] PP_Var[] live_vars,
[in] uint32_t array_size);
+
+ /**
+ * Sets the threshold size at which point we switch from transmitting
+ * array buffers in IPC messages to using shared memory. This is only used
+ * for testing purposes where we need to transmit small buffers using shmem
+ * (in order to have fast tests). Passing a value of 0 resets the threshold
+ * to its default. The threshold is in bytes.
+ */
+ [version=0.92]
+ void SetMinimumArrayBufferSizeForShmem([in] PP_Instance instance,
+ [in] uint32_t threshold);
};
diff --git a/ppapi/c/dev/ppb_testing_dev.h b/ppapi/c/dev/ppb_testing_dev.h
index 0567120..e5078e2 100644
--- a/ppapi/c/dev/ppb_testing_dev.h
+++ b/ppapi/c/dev/ppb_testing_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_testing_dev.idl modified Mon Mar 19 12:02:10 2012. */
+/* From dev/ppb_testing_dev.idl modified Thu Apr 18 13:22:09 2013. */
#ifndef PPAPI_C_DEV_PPB_TESTING_DEV_H_
#define PPAPI_C_DEV_PPB_TESTING_DEV_H_
@@ -21,7 +21,8 @@
#define PPB_TESTING_DEV_INTERFACE_0_8 "PPB_Testing(Dev);0.8"
#define PPB_TESTING_DEV_INTERFACE_0_9 "PPB_Testing(Dev);0.9"
#define PPB_TESTING_DEV_INTERFACE_0_91 "PPB_Testing(Dev);0.91"
-#define PPB_TESTING_DEV_INTERFACE PPB_TESTING_DEV_INTERFACE_0_91
+#define PPB_TESTING_DEV_INTERFACE_0_92 "PPB_Testing(Dev);0.92"
+#define PPB_TESTING_DEV_INTERFACE PPB_TESTING_DEV_INTERFACE_0_92
/**
* @file
@@ -35,7 +36,7 @@
* @addtogroup Interfaces
* @{
*/
-struct PPB_Testing_Dev_0_91 {
+struct PPB_Testing_Dev_0_92 {
/**
* Reads the bitmap data out of the backing store for the given
* DeviceContext2D and into the given image. If the data was successfully
@@ -134,9 +135,18 @@ struct PPB_Testing_Dev_0_91 {
* of the returned PP_Vars will *not* be affected by this call.
*/
uint32_t (*GetLiveVars)(struct PP_Var live_vars[], uint32_t array_size);
+ /**
+ * Sets the threshold size at which point we switch from transmitting
+ * array buffers in IPC messages to using shared memory. This is only used
+ * for testing purposes where we need to transmit small buffers using shmem
+ * (in order to have fast tests). Passing a value of 0 resets the threshold
+ * to its default. The threshold is in bytes.
+ */
+ void (*SetMinimumArrayBufferSizeForShmem)(PP_Instance instance,
+ uint32_t threshold);
};
-typedef struct PPB_Testing_Dev_0_91 PPB_Testing_Dev;
+typedef struct PPB_Testing_Dev_0_92 PPB_Testing_Dev;
struct PPB_Testing_Dev_0_7 {
PP_Bool (*ReadImageData)(PP_Resource device_context_2d,
@@ -171,6 +181,20 @@ struct PPB_Testing_Dev_0_9 {
struct PP_Var (*GetDocumentURL)(PP_Instance instance,
struct PP_URLComponents_Dev* components);
};
+
+struct PPB_Testing_Dev_0_91 {
+ PP_Bool (*ReadImageData)(PP_Resource device_context_2d,
+ PP_Resource image,
+ const struct PP_Point* top_left);
+ void (*RunMessageLoop)(PP_Instance instance);
+ void (*QuitMessageLoop)(PP_Instance instance);
+ uint32_t (*GetLiveObjectsForInstance)(PP_Instance instance);
+ PP_Bool (*IsOutOfProcess)(void);
+ void (*SimulateInputEvent)(PP_Instance instance, PP_Resource input_event);
+ struct PP_Var (*GetDocumentURL)(PP_Instance instance,
+ struct PP_URLComponents_Dev* components);
+ uint32_t (*GetLiveVars)(struct PP_Var live_vars[], uint32_t array_size);
+};
/**
* @}
*/
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index c07d029..70cb674 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -215,6 +215,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_7;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_8;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_9;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_91;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_92;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Trace_Event_Dev_0_1;
@@ -2200,6 +2201,64 @@ uint32_t Pnacl_M18_PPB_Testing_Dev_GetLiveVars(struct PP_Var live_vars[], uint32
/* End wrapper methods for PPB_Testing_Dev_0_91 */
+/* Begin wrapper methods for PPB_Testing_Dev_0_92 */
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M28_PPB_Testing_Dev_ReadImageData(PP_Resource device_context_2d, PP_Resource image, const struct PP_Point* top_left) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ return iface->ReadImageData(device_context_2d, image, top_left);
+}
+
+static __attribute__((pnaclcall))
+void Pnacl_M28_PPB_Testing_Dev_RunMessageLoop(PP_Instance instance) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ iface->RunMessageLoop(instance);
+}
+
+static __attribute__((pnaclcall))
+void Pnacl_M28_PPB_Testing_Dev_QuitMessageLoop(PP_Instance instance) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ iface->QuitMessageLoop(instance);
+}
+
+static __attribute__((pnaclcall))
+uint32_t Pnacl_M28_PPB_Testing_Dev_GetLiveObjectsForInstance(PP_Instance instance) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ return iface->GetLiveObjectsForInstance(instance);
+}
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M28_PPB_Testing_Dev_IsOutOfProcess(void) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ return iface->IsOutOfProcess();
+}
+
+static __attribute__((pnaclcall))
+void Pnacl_M28_PPB_Testing_Dev_SimulateInputEvent(PP_Instance instance, PP_Resource input_event) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ iface->SimulateInputEvent(instance, input_event);
+}
+
+static __attribute__((pnaclcall))
+struct PP_Var Pnacl_M28_PPB_Testing_Dev_GetDocumentURL(PP_Instance instance, struct PP_URLComponents_Dev* components) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ return iface->GetDocumentURL(instance, components);
+}
+
+static __attribute__((pnaclcall))
+uint32_t Pnacl_M28_PPB_Testing_Dev_GetLiveVars(struct PP_Var live_vars[], uint32_t array_size) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ return iface->GetLiveVars(live_vars, array_size);
+}
+
+static __attribute__((pnaclcall))
+void Pnacl_M28_PPB_Testing_Dev_SetMinimumArrayBufferSizeForShmem(PP_Instance instance, uint32_t threshold) {
+ const struct PPB_Testing_Dev_0_92 *iface = Pnacl_WrapperInfo_PPB_Testing_Dev_0_92.real_iface;
+ iface->SetMinimumArrayBufferSizeForShmem(instance, threshold);
+}
+
+/* End wrapper methods for PPB_Testing_Dev_0_92 */
+
/* Not generating wrapper methods for PPB_TextInput_Dev_0_1 */
/* Not generating wrapper methods for PPB_TextInput_Dev_0_2 */
@@ -4595,6 +4654,18 @@ struct PPB_Testing_Dev_0_91 Pnacl_Wrappers_PPB_Testing_Dev_0_91 = {
.GetLiveVars = (uint32_t (*)(struct PP_Var live_vars[], uint32_t array_size))&Pnacl_M18_PPB_Testing_Dev_GetLiveVars
};
+struct PPB_Testing_Dev_0_92 Pnacl_Wrappers_PPB_Testing_Dev_0_92 = {
+ .ReadImageData = (PP_Bool (*)(PP_Resource device_context_2d, PP_Resource image, const struct PP_Point* top_left))&Pnacl_M28_PPB_Testing_Dev_ReadImageData,
+ .RunMessageLoop = (void (*)(PP_Instance instance))&Pnacl_M28_PPB_Testing_Dev_RunMessageLoop,
+ .QuitMessageLoop = (void (*)(PP_Instance instance))&Pnacl_M28_PPB_Testing_Dev_QuitMessageLoop,
+ .GetLiveObjectsForInstance = (uint32_t (*)(PP_Instance instance))&Pnacl_M28_PPB_Testing_Dev_GetLiveObjectsForInstance,
+ .IsOutOfProcess = (PP_Bool (*)(void))&Pnacl_M28_PPB_Testing_Dev_IsOutOfProcess,
+ .SimulateInputEvent = (void (*)(PP_Instance instance, PP_Resource input_event))&Pnacl_M28_PPB_Testing_Dev_SimulateInputEvent,
+ .GetDocumentURL = (struct PP_Var (*)(PP_Instance instance, struct PP_URLComponents_Dev* components))&Pnacl_M28_PPB_Testing_Dev_GetDocumentURL,
+ .GetLiveVars = (uint32_t (*)(struct PP_Var live_vars[], uint32_t array_size))&Pnacl_M28_PPB_Testing_Dev_GetLiveVars,
+ .SetMinimumArrayBufferSizeForShmem = (void (*)(PP_Instance instance, uint32_t threshold))&Pnacl_M28_PPB_Testing_Dev_SetMinimumArrayBufferSizeForShmem
+};
+
/* Not generating wrapper interface for PPB_TextInput_Dev_0_1 */
/* Not generating wrapper interface for PPB_TextInput_Dev_0_2 */
@@ -5535,6 +5606,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_91 = {
.real_iface = NULL
};
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Testing_Dev_0_92 = {
+ .iface_macro = PPB_TESTING_DEV_INTERFACE_0_92,
+ .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_Testing_Dev_0_92,
+ .real_iface = NULL
+};
+
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_1 = {
.iface_macro = PPB_TEXTINPUT_DEV_INTERFACE_0_1,
.wrapped_iface = NULL /* Still need slot for real_iface */,
@@ -6024,6 +6101,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_Testing_Dev_0_8,
&Pnacl_WrapperInfo_PPB_Testing_Dev_0_9,
&Pnacl_WrapperInfo_PPB_Testing_Dev_0_91,
+ &Pnacl_WrapperInfo_PPB_Testing_Dev_0_92,
&Pnacl_WrapperInfo_PPB_TextInput_Dev_0_1,
&Pnacl_WrapperInfo_PPB_TextInput_Dev_0_2,
&Pnacl_WrapperInfo_PPB_Trace_Event_Dev_0_1,
diff --git a/ppapi/proxy/handle_converter.cc b/ppapi/proxy/handle_converter.cc
index ef4102c..4c7d282 100644
--- a/ppapi/proxy/handle_converter.cc
+++ b/ppapi/proxy/handle_converter.cc
@@ -44,18 +44,28 @@ void ConvertHandlesInParam(const ppapi::proxy::SerializedHandle& handle,
WriteHandle((*handle_index)++, handle, msg);
}
+void HandleWriter(int* handle_index,
+ IPC::Message* m,
+ const ppapi::proxy::SerializedHandle& handle) {
+ WriteHandle((*handle_index)++, handle, m);
+}
+
void ConvertHandlesInParam(const ppapi::proxy::SerializedVar& var,
Handles* handles,
IPC::Message* msg,
int* handle_index) {
- ppapi::proxy::SerializedHandle *handle = var.GetPluginShmemHandle();
- if (handle) {
- handles->push_back(*handle);
- if (msg) {
- var.WriteRawVarHeader(msg);
- WriteHandle((*handle_index)++, *handle, msg);
- }
- }
+ if (!var.raw_var_data())
+ return;
+
+ std::vector<ppapi::proxy::SerializedHandle*> var_handles =
+ var.raw_var_data()->GetHandles();
+ if (var_handles.empty())
+ return;
+
+ for (size_t i = 0; i < var_handles.size(); ++i)
+ handles->push_back(*var_handles[i]);
+ if (msg)
+ var.raw_var_data()->Write(msg, base::Bind(&HandleWriter, handle_index));
}
// For PpapiMsg_ResourceReply and the reply to PpapiHostMsg_ResourceSyncCall,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 42ef363..215791d 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1139,6 +1139,9 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance,
IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBTesting_SimulateInputEvent,
PP_Instance /* instance */,
ppapi::InputEventData /* input_event */)
+IPC_SYNC_MESSAGE_ROUTED1_0(
+ PpapiHostMsg_PPBTesting_SetMinimumArrayBufferSizeForShmem,
+ uint32_t /* threshold */)
#if !defined(OS_NACL) && !defined(NACL_WIN64)
diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc
index 167a91e..6cdf598 100644
--- a/ppapi/proxy/ppb_testing_proxy.cc
+++ b/ppapi/proxy/ppb_testing_proxy.cc
@@ -114,6 +114,18 @@ uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) {
return vars.size();
}
+void SetMinimumArrayBufferSizeForShmem(PP_Instance instance,
+ uint32_t threshold) {
+ ProxyAutoLock lock;
+ RawVarDataGraph::SetMinimumArrayBufferSizeForShmemForTest(threshold);
+ PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
+ if (!dispatcher)
+ return;
+ dispatcher->Send(
+ new PpapiHostMsg_PPBTesting_SetMinimumArrayBufferSizeForShmem(
+ API_ID_PPB_TESTING, threshold));
+}
+
const PPB_Testing_Dev testing_interface = {
&ReadImageData,
&RunMessageLoop,
@@ -122,7 +134,8 @@ const PPB_Testing_Dev testing_interface = {
&IsOutOfProcess,
&SimulateInputEvent,
&GetDocumentURL,
- &GetLiveVars
+ &GetLiveVars,
+ &SetMinimumArrayBufferSizeForShmem
};
InterfaceProxy* CreateTestingProxy(Dispatcher* dispatcher) {
@@ -167,6 +180,9 @@ bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) {
OnMsgGetLiveObjectsForInstance)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_SimulateInputEvent,
OnMsgSimulateInputEvent)
+ IPC_MESSAGE_HANDLER(
+ PpapiHostMsg_PPBTesting_SetMinimumArrayBufferSizeForShmem,
+ OnMsgSetMinimumArrayBufferSizeForShmem)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -203,5 +219,10 @@ void PPB_Testing_Proxy::OnMsgSimulateInputEvent(
input_event_impl->pp_resource());
}
+void PPB_Testing_Proxy::OnMsgSetMinimumArrayBufferSizeForShmem(
+ uint32_t threshold) {
+ RawVarDataGraph::SetMinimumArrayBufferSizeForShmemForTest(threshold);
+}
+
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h
index c6dd373..61af47f 100644
--- a/ppapi/proxy/ppb_testing_proxy.h
+++ b/ppapi/proxy/ppb_testing_proxy.h
@@ -41,6 +41,7 @@ class PPB_Testing_Proxy : public InterfaceProxy {
void OnMsgGetLiveObjectsForInstance(PP_Instance instance, uint32_t* result);
void OnMsgSimulateInputEvent(PP_Instance instance,
const ppapi::InputEventData& input_event);
+ void OnMsgSetMinimumArrayBufferSizeForShmem(uint32_t threshold);
// When this proxy is in the host side, this value caches the interface
// pointer so we don't have to retrieve it from the dispatcher each time.
diff --git a/ppapi/proxy/raw_var_data.cc b/ppapi/proxy/raw_var_data.cc
index 1c91556f..d4ad279 100644
--- a/ppapi/proxy/raw_var_data.cc
+++ b/ppapi/proxy/raw_var_data.cc
@@ -28,6 +28,8 @@ namespace {
// memory instead of sending the data over IPC. Light testing suggests
// shared memory is much faster for 256K and larger messages.
static const uint32 kMinimumArrayBufferSizeForShmem = 256 * 1024;
+static uint32 g_minimum_array_buffer_size_for_shmem =
+ kMinimumArrayBufferSizeForShmem;
void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) {
IPC::ParamTraits<SerializedHandle>::Write(m, handle);
@@ -174,6 +176,25 @@ scoped_ptr<RawVarDataGraph> RawVarDataGraph::Read(const IPC::Message* m,
return result.Pass();
}
+std::vector<SerializedHandle*> RawVarDataGraph::GetHandles() {
+ std::vector<SerializedHandle*> result;
+ for (size_t i = 0; i < data_.size(); ++i) {
+ SerializedHandle* handle = data_[i]->GetHandle();
+ if (handle)
+ result.push_back(handle);
+ }
+ return result;
+}
+
+// static
+void RawVarDataGraph::SetMinimumArrayBufferSizeForShmemForTest(
+ uint32 threshold) {
+ if (threshold == 0)
+ g_minimum_array_buffer_size_for_shmem = kMinimumArrayBufferSizeForShmem;
+ else
+ g_minimum_array_buffer_size_for_shmem = threshold;
+}
+
// RawVarData ------------------------------------------------------------------
// static
@@ -205,6 +226,10 @@ RawVarData::RawVarData() : initialized_(false) {
RawVarData::~RawVarData() {
}
+SerializedHandle* RawVarData::GetHandle() {
+ return NULL;
+}
+
// BasicRawVarData -------------------------------------------------------------
BasicRawVarData::BasicRawVarData() {
}
@@ -355,7 +380,7 @@ bool ArrayBufferRawVarData::Init(const PP_Var& var,
if (!buffer_var)
return false;
bool using_shmem = false;
- if (buffer_var->ByteLength() >= kMinimumArrayBufferSizeForShmem &&
+ if (buffer_var->ByteLength() >= g_minimum_array_buffer_size_for_shmem &&
instance != 0) {
int host_handle_id;
base::SharedMemoryHandle plugin_handle;
@@ -363,7 +388,7 @@ bool ArrayBufferRawVarData::Init(const PP_Var& var,
&host_handle_id,
&plugin_handle);
if (using_shmem) {
- if (host_shm_handle_id_ != -1) {
+ if (host_handle_id != -1) {
DCHECK(!base::SharedMemory::IsHandleValid(plugin_handle));
DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
type_ = ARRAY_BUFFER_SHMEM_HOST;
@@ -476,6 +501,12 @@ bool ArrayBufferRawVarData::Read(PP_VarType type,
return true;
}
+SerializedHandle* ArrayBufferRawVarData::GetHandle() {
+ if (type_ == ARRAY_BUFFER_SHMEM_PLUGIN && plugin_shm_handle_.size() != 0)
+ return &plugin_shm_handle_;
+ return NULL;
+}
+
// ArrayRawVarData -------------------------------------------------------------
ArrayRawVarData::ArrayRawVarData() {
}
diff --git a/ppapi/proxy/raw_var_data.h b/ppapi/proxy/raw_var_data.h
index 17bdaee..1e8746f 100644
--- a/ppapi/proxy/raw_var_data.h
+++ b/ppapi/proxy/raw_var_data.h
@@ -72,6 +72,16 @@ class PPAPI_PROXY_EXPORT RawVarDataGraph {
static scoped_ptr<RawVarDataGraph> Read(const IPC::Message* m,
PickleIterator* iter);
+ // Returns a vector of SerializedHandles associated with this RawVarDataGraph.
+ // Ownership of the pointers remains with the elements of the RawVarDataGraph.
+ std::vector<SerializedHandle*> GetHandles();
+
+ // Sets the threshold size at which point we switch from transmitting
+ // array buffers in IPC messages to using shared memory. This is only used
+ // for testing purposes where we need to transmit small buffers using shmem
+ // (in order to have fast tests).
+ static void SetMinimumArrayBufferSizeForShmemForTest(uint32 threshold);
+
// A list of the nodes in the graph.
ScopedVector<RawVarData> data_;
};
@@ -107,6 +117,10 @@ class RawVarData {
const IPC::Message* m,
PickleIterator* iter) = 0;
+ // Returns a SerializedHandle associated with this RawVarData or NULL if none
+ // exists. Ownership of the pointer remains with the RawVarData.
+ virtual SerializedHandle* GetHandle();
+
bool initialized() { return initialized_; }
protected:
@@ -182,6 +196,7 @@ class ArrayBufferRawVarData : public RawVarData {
virtual bool Read(PP_VarType type,
const IPC::Message* m,
PickleIterator* iter) OVERRIDE;
+ virtual SerializedHandle* GetHandle() OVERRIDE;
private:
// The type of the storage underlying the array buffer.
diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc
index 698d920..2f4a396 100644
--- a/ppapi/proxy/serialized_var.cc
+++ b/ppapi/proxy/serialized_var.cc
@@ -18,11 +18,6 @@
namespace ppapi {
namespace proxy {
-// When sending array buffers, if the size is over 256K, we use shared
-// memory instead of sending the data over IPC. Light testing suggests
-// shared memory is much faster for 256K and larger messages.
-static const uint32 kMinimumArrayBufferSizeForShmem = 256 * 1024;
-
// SerializedVar::Inner --------------------------------------------------------
SerializedVar::Inner::Inner()
@@ -63,7 +58,16 @@ SerializedVar::Inner::~Inner() {
PP_Var SerializedVar::Inner::GetVar() {
DCHECK(serialization_rules_);
- ConvertRawVarData();
+#if defined(NACL_WIN64)
+ NOTREACHED();
+ return PP_MakeUndefined();
+#endif
+
+ if (raw_var_data_.get()) {
+ var_ = raw_var_data_->CreatePPVar(instance_);
+ raw_var_data_.reset(NULL);
+ }
+
return var_;
}
@@ -84,21 +88,6 @@ void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) {
raw_var_data_.reset(NULL);
}
-void SerializedVar::Inner::WriteRawVarHeader(IPC::Message* m) const {
- // Write raw_var_data_ when we're called from
- // chrome/nacl/nacl_ipc_adapter.cc.
- DCHECK(raw_var_data_.get());
- DCHECK_EQ(PP_VARTYPE_ARRAY_BUFFER, raw_var_data_->type);
- DCHECK(raw_var_data_->shmem_size != 0);
-
- // The serialization for this message MUST MATCH the implementation at
- // SerializedVar::Inner::WriteToMessage for ARRAY_BUFFER_SHMEM_PLUGIN.
- m->WriteInt(static_cast<int>(raw_var_data_->type));
- m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
- m->WriteInt(raw_var_data_->shmem_size);
- // NaClIPCAdapter will write the handles for us.
-}
-
void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
// When writing to the IPC messages, a serialization rules handler should
// always have been set.
@@ -118,92 +107,7 @@ void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
DCHECK(!has_been_serialized_);
has_been_serialized_ = true;
#endif
-
- DCHECK(!raw_var_data_.get());
- m->WriteInt(static_cast<int>(var_.type));
- switch (var_.type) {
- case PP_VARTYPE_UNDEFINED:
- case PP_VARTYPE_NULL:
- // These don't need any data associated with them other than the type we
- // just serialized.
- break;
- case PP_VARTYPE_BOOL:
- m->WriteBool(PP_ToBool(var_.value.as_bool));
- break;
- case PP_VARTYPE_INT32:
- m->WriteInt(var_.value.as_int);
- break;
- case PP_VARTYPE_DOUBLE:
- IPC::ParamTraits<double>::Write(m, var_.value.as_double);
- break;
- case PP_VARTYPE_STRING: {
- // TODO(brettw) in the case of an invalid string ID, it would be nice
- // to send something to the other side such that a 0 ID would be
- // generated there. Then the function implementing the interface can
- // handle the invalid string as if it was in process rather than seeing
- // what looks like a valid empty string.
- StringVar* string_var = StringVar::FromPPVar(var_);
- m->WriteString(string_var ? *string_var->ptr() : std::string());
- break;
- }
- case PP_VARTYPE_ARRAY_BUFFER: {
- // TODO(dmichael) in the case of an invalid var ID, it would be nice
- // to send something to the other side such that a 0 ID would be
- // generated there. Then the function implementing the interface can
- // handle the invalid string as if it was in process rather than seeing
- // what looks like a valid empty ArraryBuffer.
- ArrayBufferVar* buffer_var = ArrayBufferVar::FromPPVar(var_);
- bool using_shmem = false;
- if (buffer_var &&
- buffer_var->ByteLength() >= kMinimumArrayBufferSizeForShmem &&
- instance_ != 0) {
- int host_shm_handle_id;
- base::SharedMemoryHandle plugin_shm_handle;
- using_shmem = buffer_var->CopyToNewShmem(instance_,
- &host_shm_handle_id,
- &plugin_shm_handle);
- if (using_shmem) {
- // The serialization for this message MUST MATCH the implementation
- // at SerializedVar::Inner::WriteRawVarHeader for
- // ARRAY_BUFFER_SHMEM_PLUGIN.
- if (host_shm_handle_id != -1) {
- DCHECK(!base::SharedMemory::IsHandleValid(plugin_shm_handle));
- DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
- m->WriteInt(ARRAY_BUFFER_SHMEM_HOST);
- m->WriteInt(host_shm_handle_id);
- } else {
- DCHECK(base::SharedMemory::IsHandleValid(plugin_shm_handle));
- DCHECK(PpapiGlobals::Get()->IsHostGlobals());
- m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
- m->WriteInt(buffer_var->ByteLength());
- SerializedHandle handle(plugin_shm_handle,
- buffer_var->ByteLength());
- IPC::ParamTraits<SerializedHandle>::Write(m, handle);
- }
- }
- }
- if (!using_shmem) {
- if (buffer_var) {
- m->WriteInt(ARRAY_BUFFER_NO_SHMEM);
- m->WriteData(static_cast<const char*>(buffer_var->Map()),
- buffer_var->ByteLength());
- } else {
- // TODO(teravest): Introduce an ARRAY_BUFFER_EMPTY message type.
- m->WriteBool(ARRAY_BUFFER_NO_SHMEM);
- m->WriteData(NULL, 0);
- }
- }
- break;
- }
- case PP_VARTYPE_OBJECT:
- m->WriteInt64(var_.value.as_id);
- break;
- case PP_VARTYPE_ARRAY:
- case PP_VARTYPE_DICTIONARY:
- // TODO(yzshen) when these are supported, implement this.
- NOTIMPLEMENTED();
- break;
- }
+ RawVarDataGraph::Create(var_, instance_)->Write(m);
}
bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
@@ -221,99 +125,8 @@ bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
#endif
// When reading, the dispatcher should be set when we get a Deserialize
// call (which will supply a dispatcher).
- int type;
- if (!m->ReadInt(iter, &type))
- return false;
-
- bool success = false;
- switch (type) {
- case PP_VARTYPE_UNDEFINED:
- case PP_VARTYPE_NULL:
- // These don't have any data associated with them other than the type we
- // just serialized.
- success = true;
- break;
- case PP_VARTYPE_BOOL: {
- bool bool_value;
- success = m->ReadBool(iter, &bool_value);
- var_.value.as_bool = PP_FromBool(bool_value);
- break;
- }
- case PP_VARTYPE_INT32:
- success = m->ReadInt(iter, &var_.value.as_int);
- break;
- case PP_VARTYPE_DOUBLE:
- success = IPC::ParamTraits<double>::Read(m, iter, &var_.value.as_double);
- break;
- case PP_VARTYPE_STRING: {
- raw_var_data_.reset(new RawVarData);
- raw_var_data_->type = PP_VARTYPE_STRING;
- success = m->ReadString(iter, &raw_var_data_->data);
- if (!success)
- raw_var_data_.reset(NULL);
- break;
- }
- case PP_VARTYPE_ARRAY_BUFFER: {
- int length = 0;
- const char* message_bytes = NULL;
- int shmem_type;
- success = m->ReadInt(iter, &shmem_type);
- if (success) {
- if (shmem_type == ARRAY_BUFFER_NO_SHMEM) {
- success = m->ReadData(iter, &message_bytes, &length);
- if (success) {
- raw_var_data_.reset(new RawVarData);
- raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
- raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
- raw_var_data_->shmem_size = 0;
- raw_var_data_->data.assign(message_bytes, length);
- }
- } else if (shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
- int host_handle_id;
- success = m->ReadInt(iter, &host_handle_id);
- if (success) {
- raw_var_data_.reset(new RawVarData);
- raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
- raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
- raw_var_data_->host_handle_id = host_handle_id;
- }
- } else if (shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
- SerializedHandle plugin_handle;
- success = m->ReadInt(iter, &length);
- success &= IPC::ParamTraits<SerializedHandle>::Read(
- m, iter, &plugin_handle);
- if (success) {
- raw_var_data_.reset(new RawVarData);
- raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
- raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
- raw_var_data_->shmem_size = length;
- raw_var_data_->plugin_handle = plugin_handle;
- }
- }
- }
- break;
- }
- case PP_VARTYPE_OBJECT:
- success = m->ReadInt64(iter, &var_.value.as_id);
- break;
- case PP_VARTYPE_ARRAY:
- case PP_VARTYPE_DICTIONARY:
- // TODO(yzshen) when these types are supported, implement this.
- NOTIMPLEMENTED();
- break;
- default:
- // Leave success as false.
- break;
- }
-
- // All success cases get here. We avoid writing the type above so that the
- // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the
- // failure case.
- // We also don't write the type if |raw_var_data_| is set. |var_| will be
- // updated lazily when GetVar() is called.
- if (success && !raw_var_data_.get())
- var_.type = static_cast<PP_VarType>(type);
- return success;
+ raw_var_data_ = RawVarDataGraph::Read(m, iter);
+ return raw_var_data_.get() != NULL;
}
void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() {
@@ -324,66 +137,6 @@ void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() {
cleanup_mode_ = END_RECEIVE_CALLER_OWNED;
}
-void SerializedVar::Inner::ConvertRawVarData() {
-#if defined(NACL_WIN64)
- NOTREACHED();
-#else
- if (!raw_var_data_.get())
- return;
-
- DCHECK_EQ(PP_VARTYPE_UNDEFINED, var_.type);
- switch (raw_var_data_->type) {
- case PP_VARTYPE_STRING: {
- var_ = StringVar::SwapValidatedUTF8StringIntoPPVar(
- &raw_var_data_->data);
- break;
- }
- case PP_VARTYPE_ARRAY_BUFFER: {
- if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
- base::SharedMemoryHandle host_handle;
- uint32 size_in_bytes;
- bool ok =
- PpapiGlobals::Get()->GetVarTracker()->
- StopTrackingSharedMemoryHandle(raw_var_data_->host_handle_id,
- instance_,
- &host_handle,
- &size_in_bytes);
- if (ok) {
- var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
- size_in_bytes, host_handle);
- } else {
- LOG(ERROR) << "Couldn't find array buffer id: "
- << raw_var_data_->host_handle_id;
- var_ = PP_MakeUndefined();
- }
- } else if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
- var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
- raw_var_data_->shmem_size,
- raw_var_data_->plugin_handle.shmem());
- } else {
- var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
- static_cast<uint32>(raw_var_data_->data.size()),
- raw_var_data_->data.data());
- }
- break;
- }
- default:
- NOTREACHED();
- }
- raw_var_data_.reset(NULL);
-#endif
-}
-
-SerializedHandle* SerializedVar::Inner::GetPluginShmemHandle() const {
- if (raw_var_data_.get()) {
- if (raw_var_data_->type == PP_VARTYPE_ARRAY_BUFFER) {
- if (raw_var_data_->shmem_size != 0)
- return &raw_var_data_->plugin_handle;
- }
- }
- return NULL;
-}
-
// SerializedVar ---------------------------------------------------------------
SerializedVar::SerializedVar() : inner_(new Inner) {
diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h
index f283590..7c3349f 100644
--- a/ppapi/proxy/serialized_var.h
+++ b/ppapi/proxy/serialized_var.h
@@ -15,6 +15,7 @@
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/proxy/raw_var_data.h"
#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/proxy/var_serialization_rules.h"
@@ -83,12 +84,8 @@ class PPAPI_PROXY_EXPORT SerializedVar {
return inner_->ReadFromMessage(m, iter);
}
- // Used by chrome/nacl/nacl_ipc_adapter.cc
- SerializedHandle* GetPluginShmemHandle() const {
- return inner_->GetPluginShmemHandle();
- }
- void WriteRawVarHeader(IPC::Message* m) const {
- inner_->WriteRawVarHeader(m);
+ RawVarDataGraph* raw_var_data() const {
+ return inner_->raw_var_data();
}
protected:
@@ -113,6 +110,10 @@ class PPAPI_PROXY_EXPORT SerializedVar {
serialization_rules_ = serialization_rules;
}
+ RawVarDataGraph* raw_var_data() {
+ return raw_var_data_.get();
+ }
+
// See outer class's declarations above.
PP_Var GetVar();
void SetVar(PP_Var var);
@@ -129,12 +130,6 @@ class PPAPI_PROXY_EXPORT SerializedVar {
void SetCleanupModeToEndSendPassRef();
void SetCleanupModeToEndReceiveCallerOwned();
- // Returns a handle in the underlying data, if it exists.
- SerializedHandle* GetPluginShmemHandle() const;
-
- // Writes raw var data, excluding handles.
- void WriteRawVarHeader(IPC::Message* m) const;
-
private:
enum CleanupMode {
// The serialized var won't do anything special in the destructor
@@ -148,32 +143,6 @@ class PPAPI_PROXY_EXPORT SerializedVar {
END_RECEIVE_CALLER_OWNED
};
- // Enum for array buffer message types.
- enum ShmemType {
- ARRAY_BUFFER_NO_SHMEM,
- ARRAY_BUFFER_SHMEM_HOST,
- ARRAY_BUFFER_SHMEM_PLUGIN,
- };
-
- // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
- // reply to a sync message. We cannot use the var tracker on the I/O thread,
- // which means we cannot create PP_Var for PP_VARTYPE_STRING and
- // PP_VARTYPE_ARRAY_BUFFER in ReadFromMessage(). So we save the raw var data
- // and create PP_Var later when GetVar() is called, which should happen on
- // the main thread.
- struct RawVarData {
- PP_VarType type;
- ShmemType shmem_type;
- std::string data;
- uint32 shmem_size;
- int host_handle_id;
- SerializedHandle plugin_handle;
- };
-
- // Converts |raw_var_data_| to |var_|. It is a no-op if |raw_var_data_| is
- // NULL.
- void ConvertRawVarData();
-
// Rules for serializing and deserializing vars for this process type.
// This may be NULL, but must be set before trying to serialize to IPC when
// sending, or before converting back to a PP_Var when receiving.
@@ -200,10 +169,12 @@ class PPAPI_PROXY_EXPORT SerializedVar {
mutable bool has_been_deserialized_;
#endif
- // It will be non-NULL if there is PP_VARTYPE_STRING or
- // PP_VARTYPE_ARRAY_BUFFER data from ReadFromMessage() that hasn't been
- // converted to PP_Var.
- scoped_ptr<RawVarData> raw_var_data_;
+ // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
+ // reply to a sync message. We cannot use the var tracker on the I/O thread,
+ // which means we cannot create some types of PP_Var
+ // (e.g. PP_VARTYPE_STRING). The data is stored in |raw_var_data_| and the
+ // PP_Var is constructed when |GetVar()| is called.
+ scoped_ptr<RawVarDataGraph> raw_var_data_;
DISALLOW_COPY_AND_ASSIGN(Inner);
};
@@ -499,9 +470,6 @@ class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
public:
explicit SerializedVarTestReader(const SerializedVar& var);
- // The "incomplete" var is the one sent over the wire. Strings and object
- // IDs have not yet been converted, so this is the thing that tests will
- // actually want to check.
PP_Var GetVar() const { return inner_->GetVar(); }
};
diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc
index 8b16620..39102e1 100644
--- a/ppapi/tests/test_post_message.cc
+++ b/ppapi/tests/test_post_message.cc
@@ -58,6 +58,23 @@ void InvokePostMessageThreadFunc(void* user_data) {
delete arg;
}
+class ScopedArrayBufferSizeSetter {
+ public:
+ ScopedArrayBufferSizeSetter(const PPB_Testing_Dev* interface,
+ PP_Instance instance,
+ uint32_t threshold)
+ : interface_(interface),
+ instance_(instance) {
+ interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold);
+ }
+ ~ScopedArrayBufferSizeSetter() {
+ interface_->SetMinimumArrayBufferSizeForShmem(instance_, 0);
+ }
+ private:
+ const PPB_Testing_Dev* interface_;
+ PP_Instance instance_;
+};
+
#define FINISHED_WAITING_MESSAGE "TEST_POST_MESSAGE_FINISHED_WAITING"
} // namespace
@@ -261,11 +278,10 @@ std::string TestPostMessage::TestSendingArrayBuffer() {
// TODO(sehr,dmichael): Add testing of longer array buffers when
// crbug.com/110086 is fixed.
-#if defined(OS_LINUX)
- uint32_t sizes[] = { 0, 100, 1000, 10000, 100000, 1000000 };
-#else
- uint32_t sizes[] = { 0, 100, 1000, 10000, 100000 };
-#endif
+ ScopedArrayBufferSizeSetter setter(testing_interface_,
+ instance_->pp_instance(),
+ 200);
+ uint32_t sizes[] = { 0, 100, 1000, 10000 };
for (size_t i = 0; i < sizeof(sizes)/sizeof(sizes[i]); ++i) {
std::ostringstream size_stream;
size_stream << sizes[i];