Bug 570096: Implement serialization of a grab-bag of gfx types. r=joe

This commit is contained in:
Chris Jones 2010-06-21 15:35:48 -05:00
parent 6af3d8672d
commit ac67f4dbc4
6 changed files with 248 additions and 1 deletions

View File

@ -44,7 +44,12 @@
#include "prtypes.h"
#include "nsStringGlue.h"
#include "nsTArray.h"
#include "gfx3DMatrix.h"
#include "gfxColor.h"
#include "gfxMatrix.h"
#include "gfxPattern.h"
#include "nsRect.h"
#include "nsRegion.h"
#ifdef _MSC_VER
#pragma warning( disable : 4800 )
@ -53,6 +58,8 @@
namespace mozilla {
typedef gfxPattern::GraphicsFilter GraphicsFilterType;
// XXX there are out of place and might be generally useful. Could
// move to nscore.h or something.
struct void_t {
@ -250,6 +257,7 @@ struct ParamTraits<nsTArray<E> >
return false;
}
aResult->SetCapacity(length);
for (PRUint32 index = 0; index < length; index++) {
E* element = aResult->AppendElement();
if (!(element && ReadParam(aMsg, aIter, element))) {
@ -331,6 +339,98 @@ struct ParamTraits<gfxMatrix>
}
};
template<>
struct ParamTraits<gfx3DMatrix>
{
typedef gfx3DMatrix paramType;
static void Write(Message* msg, const paramType& param)
{
#define Wr(_f) WriteParam(msg, param. _f)
Wr(_11); Wr(_12); Wr(_13); Wr(_14);
Wr(_21); Wr(_22); Wr(_23); Wr(_24);
Wr(_31); Wr(_32); Wr(_33); Wr(_34);
Wr(_41); Wr(_42); Wr(_43); Wr(_44);
#undef Wr
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
#define Rd(_f) ReadParam(msg, iter, &result-> _f)
return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44));
#undef Rd
}
};
template<>
struct ParamTraits<mozilla::GraphicsFilterType>
{
typedef mozilla::GraphicsFilterType paramType;
static void Write(Message* msg, const paramType& param)
{
switch (param) {
case gfxPattern::FILTER_FAST:
case gfxPattern::FILTER_GOOD:
case gfxPattern::FILTER_BEST:
case gfxPattern::FILTER_NEAREST:
case gfxPattern::FILTER_BILINEAR:
case gfxPattern::FILTER_GAUSSIAN:
WriteParam(msg, int32(param));
return;
default:
NS_RUNTIMEABORT("not reached");
return;
}
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
int32 filter;
if (!ReadParam(msg, iter, &filter))
return false;
switch (filter) {
case gfxPattern::FILTER_FAST:
case gfxPattern::FILTER_GOOD:
case gfxPattern::FILTER_BEST:
case gfxPattern::FILTER_NEAREST:
case gfxPattern::FILTER_BILINEAR:
case gfxPattern::FILTER_GAUSSIAN:
*result = paramType(filter);
return true;
default:
return false;
}
}
};
template<>
struct ParamTraits<gfxRGBA>
{
typedef gfxRGBA paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.r);
WriteParam(msg, param.g);
WriteParam(msg, param.b);
WriteParam(msg, param.a);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->r) &&
ReadParam(msg, iter, &result->g) &&
ReadParam(msg, iter, &result->b) &&
ReadParam(msg, iter, &result->a));
}
};
template<>
struct ParamTraits<mozilla::void_t>
{
@ -357,6 +457,91 @@ struct ParamTraits<mozilla::null_t>
}
};
template<>
struct ParamTraits<nsIntPoint>
{
typedef nsIntPoint paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.x);
WriteParam(msg, param.y);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->x) &&
ReadParam(msg, iter, &result->y));
}
};
template<>
struct ParamTraits<nsIntRect>
{
typedef nsIntRect paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.x);
WriteParam(msg, param.y);
WriteParam(msg, param.width);
WriteParam(msg, param.height);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->x) &&
ReadParam(msg, iter, &result->y) &&
ReadParam(msg, iter, &result->width) &&
ReadParam(msg, iter, &result->height));
}
};
template<>
struct ParamTraits<nsIntRegion>
{
typedef nsIntRegion paramType;
static void Write(Message* msg, const paramType& param)
{
nsIntRegionRectIterator it(param);
while (const nsIntRect* r = it.Next())
WriteParam(msg, *r);
// empty rects are sentinel values because nsRegions will never
// contain them
WriteParam(msg, nsIntRect());
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
nsIntRect rect;
while (ReadParam(msg, iter, &rect)) {
if (rect.IsEmpty())
return true;
result->Or(*result, rect);
}
return false;
}
};
template<>
struct ParamTraits<nsIntSize>
{
typedef nsIntSize paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.width);
WriteParam(msg, param.height);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->width) &&
ReadParam(msg, iter, &result->height));
}
};
} /* namespace IPC */
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

View File

@ -36,6 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsRegion.h"
#include "mozilla/ipc/IOThreadChild.h"
#include "IPDLUnitTestProcessChild.h"
@ -52,6 +54,10 @@ IPDLUnitTestProcessChild::Init()
IPDLUnitTestChildInit(IOThreadChild::channel(),
ParentHandle(),
IOThreadChild::message_loop());
if (NS_FAILED(nsRegion::InitStatic()))
return false;
return true;
}

View File

@ -10,6 +10,8 @@
#include "base/command_line.h"
#include "base/string_util.h"
#include "nsRegion.h"
#include "IPDLUnitTestSubprocess.h"
//-----------------------------------------------------------------------------
@ -130,6 +132,9 @@ IPDLUnitTestMain(void* aData)
}
gIPDLUnitTestName = testString;
if (NS_FAILED(nsRegion::InitStatic()))
fail("initializing nsRegion");
printf(MOZ_IPDL_TESTINFO_LABEL "| running test | %s\n", gIPDLUnitTestName);
std::vector<std::string> testCaseArgs;

View File

@ -1,6 +1,7 @@
include protocol PTestDataStructuresSub;
using mozilla::null_t;
using nsIntRegion;
namespace mozilla {
namespace _foo {
@ -177,6 +178,11 @@ parent:
sync Test17(Op[] ops);
// test that the ParamTraits<nsTArray>::Read() workaround for
// nsTArray's incorrect memmove() semantics works properly
// (nsIntRegion isn't memmove()able)
sync Test18(nsIntRegion[] ops);
state START:
send Start goto TEST1;
@ -196,7 +202,8 @@ state TEST13: recv Test13 goto TEST14;
state TEST14: recv Test14 goto TEST15;
state TEST15: recv Test15 goto TEST16;
state TEST16: recv Test16 goto TEST17;
state TEST17: recv Test17 goto DEAD;
state TEST17: recv Test17 goto TEST18;
state TEST18: recv Test18 goto DEAD;
state DEAD:
recv __delete__;

View File

@ -1,7 +1,11 @@
#include "mozilla/unused.h"
#include "TestDataStructures.h"
#include "IPDLUnitTests.h" // fail etc.
typedef nsTArray<nsIntRegion> RegionArray;
namespace mozilla {
namespace _ipdltest {
@ -424,6 +428,19 @@ bool TestDataStructuresParent::RecvTest17(const nsTArray<Op>& sa)
return true;
}
bool TestDataStructuresParent::RecvTest18(const RegionArray& ra)
{
for (RegionArray::index_type i = 0; i < ra.Length(); ++i) {
nsIntRegionRectIterator it(ra[i]);
// if |ra| has been realloc()d and given a different allocator
// chunk, this next line will nondeterministically crash or
// iloop
while (const nsIntRect* sr = it.Next()) unused << sr;
}
return true;
}
//-----------------------------------------------------------------------------
// child
@ -459,6 +476,7 @@ TestDataStructuresChild::RecvStart()
Test15();
Test16();
Test17();
Test18();
for (uint32 i = 0; i < nactors; ++i)
if (!PTestDataStructuresSubChild::Send__delete__(mKids[i]))
@ -897,5 +915,27 @@ TestDataStructuresChild::Test17()
printf(" passed %s\n", __FUNCTION__);
}
void
TestDataStructuresChild::Test18()
{
const int nelements = 1000;
RegionArray ra;
// big enough to hopefully force a realloc to a different chunk of
// memory on the receiving side, if the workaround isn't working
// correctly. But SetCapacity() here because we don't want to
// crash on the sending side.
ra.SetCapacity(nelements);
for (int i = 0; i < nelements; ++i) {
nsIntRegion r;
r = r.Or(nsIntRect(0, 0, 10, 10), nsIntRect(10, 10, 10, 10));
ra.AppendElement(r);
}
if (!SendTest18(ra))
fail("sending Test18");
printf(" passed %s\n", __FUNCTION__);
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -158,6 +158,9 @@ protected:
NS_OVERRIDE
virtual bool RecvTest17(const nsTArray<Op>& sa);
NS_OVERRIDE
virtual bool RecvTest18(const nsTArray<nsIntRegion>& ra);
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
@ -224,6 +227,7 @@ private:
void Test15();
void Test16();
void Test17();
void Test18();
nsTArray<PTestDataStructuresSubChild*> mKids;
};