gfx/layers/ipc/FenceUtilsGonk.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/ipc/FenceUtilsGonk.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,123 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=8 et :
     1.6 + */
     1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +#include "GLContext.h"
    1.12 +#include "mozilla/unused.h"
    1.13 +#include "nsXULAppAPI.h"
    1.14 +
    1.15 +#include "FenceUtilsGonk.h"
    1.16 +
    1.17 +using namespace android;
    1.18 +using namespace base;
    1.19 +using namespace mozilla::layers;
    1.20 +
    1.21 +namespace IPC {
    1.22 +
    1.23 +void
    1.24 +ParamTraits<FenceHandle>::Write(Message* aMsg,
    1.25 +                                const paramType& aParam)
    1.26 +{
    1.27 +#if ANDROID_VERSION >= 19
    1.28 +  sp<Fence> flattenable = aParam.mFence;
    1.29 +#else
    1.30 +  Flattenable *flattenable = aParam.mFence.get();
    1.31 +#endif
    1.32 +  size_t nbytes = flattenable->getFlattenedSize();
    1.33 +  size_t nfds = flattenable->getFdCount();
    1.34 +
    1.35 +  char data[nbytes];
    1.36 +  int fds[nfds];
    1.37 +
    1.38 +#if ANDROID_VERSION >= 19
    1.39 +  // Make a copy of "data" and "fds" for flatten() to avoid casting problem
    1.40 +  void *pdata = (void *)data;
    1.41 +  int *pfds = fds;
    1.42 +
    1.43 +  flattenable->flatten(pdata, nbytes, pfds, nfds);
    1.44 +
    1.45 +  // In Kitkat, flatten() will change the value of nbytes and nfds, which dues
    1.46 +  // to multiple parcelable object consumption. The actual size and fd count
    1.47 +  // which returned by getFlattenedSize() and getFdCount() are not changed.
    1.48 +  // So we change nbytes and nfds back by call corresponding calls.
    1.49 +  nbytes = flattenable->getFlattenedSize();
    1.50 +  nfds = flattenable->getFdCount();
    1.51 +#else
    1.52 +  flattenable->flatten(data, nbytes, fds, nfds);
    1.53 +#endif
    1.54 +  aMsg->WriteSize(nbytes);
    1.55 +  aMsg->WriteSize(nfds);
    1.56 +
    1.57 +  aMsg->WriteBytes(data, nbytes);
    1.58 +  for (size_t n = 0; n < nfds; ++n) {
    1.59 +    // These buffers can't die in transit because they're created
    1.60 +    // synchonously and the parent-side buffer can only be dropped if
    1.61 +    // there's a crash.
    1.62 +    aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false));
    1.63 +  }
    1.64 +}
    1.65 +
    1.66 +bool
    1.67 +ParamTraits<FenceHandle>::Read(const Message* aMsg,
    1.68 +                               void** aIter, paramType* aResult)
    1.69 +{
    1.70 +  size_t nbytes;
    1.71 +  size_t nfds;
    1.72 +  const char* data;
    1.73 +
    1.74 +  if (!aMsg->ReadSize(aIter, &nbytes) ||
    1.75 +      !aMsg->ReadSize(aIter, &nfds) ||
    1.76 +      !aMsg->ReadBytes(aIter, &data, nbytes)) {
    1.77 +    return false;
    1.78 +  }
    1.79 +
    1.80 +  int fds[nfds];
    1.81 +
    1.82 +  for (size_t n = 0; n < nfds; ++n) {
    1.83 +    FileDescriptor fd;
    1.84 +    if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
    1.85 +      return false;
    1.86 +    }
    1.87 +    // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does
    1.88 +    // the right thing and dup's the fd.  If it's shared cross-thread,
    1.89 +    // SCM_RIGHTS doesn't dup the fd.  That's surprising, but we just
    1.90 +    // deal with it here.  NB: only the "default" (master) process can
    1.91 +    // alloc gralloc buffers.
    1.92 +    bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
    1.93 +    int dupFd = sameProcess ? dup(fd.fd) : fd.fd;
    1.94 +    fds[n] = dupFd;
    1.95 +  }
    1.96 +
    1.97 +  sp<Fence> buffer(new Fence());
    1.98 +#if ANDROID_VERSION >= 19
    1.99 +  // Make a copy of "data" and "fds" for unflatten() to avoid casting problem
   1.100 +  void const *pdata = (void const *)data;
   1.101 +  int const *pfds = fds;
   1.102 +
   1.103 +  if (NO_ERROR == buffer->unflatten(pdata, nbytes, pfds, nfds)) {
   1.104 +#else
   1.105 +  Flattenable *flattenable = buffer.get();
   1.106 +
   1.107 +  if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) {
   1.108 +#endif
   1.109 +    aResult->mFence = buffer;
   1.110 +    return true;
   1.111 +  }
   1.112 +  return false;
   1.113 +}
   1.114 +
   1.115 +} // namespace IPC
   1.116 +
   1.117 +namespace mozilla {
   1.118 +namespace layers {
   1.119 +
   1.120 +FenceHandle::FenceHandle(const sp<Fence>& aFence)
   1.121 +  : mFence(aFence)
   1.122 +{
   1.123 +}
   1.124 +
   1.125 +} // namespace layers
   1.126 +} // namespace mozilla

mercurial