DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (fddffdeab170)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "MacIOSurfaceImage.h"
#include "mozilla/layers/CompositableClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/MacIOSurfaceTextureClientOGL.h"
#include "YCbCrUtils.h"

using namespace mozilla;
using namespace mozilla::layers;
using namespace mozilla::gfx;

TextureClient*
MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
{
  if (!mTextureClient) {
    mTextureClient = MacIOSurfaceTextureClientOGL::Create(aClient->GetForwarder(),
                                                          TextureFlags::DEFAULT,
                                                          mSurface);
  }
  return mTextureClient;
}

already_AddRefed<SourceSurface>
MacIOSurfaceImage::GetAsSourceSurface()
{
  RefPtr<DataSourceSurface> dataSurface;
  mSurface->Lock();
  size_t bytesPerRow = mSurface->GetBytesPerRow();
  size_t ioWidth = mSurface->GetDevicePixelWidth();
  size_t ioHeight = mSurface->GetDevicePixelHeight();

  SurfaceFormat format = mSurface->GetFormat() == SurfaceFormat::NV12 ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;

  dataSurface = Factory::CreateDataSourceSurface(IntSize(ioWidth, ioHeight), format);
  if (NS_WARN_IF(!dataSurface)) {
    return nullptr;
  }

  DataSourceSurface::MappedSurface mappedSurface;
  if (!dataSurface->Map(DataSourceSurface::WRITE, &mappedSurface))
    return nullptr;

  if (mSurface->GetFormat() == SurfaceFormat::NV12) {
    if (mSurface->GetDevicePixelWidth() > PlanarYCbCrImage::MAX_DIMENSION ||
        mSurface->GetDevicePixelHeight() > PlanarYCbCrImage::MAX_DIMENSION) {
      return nullptr;
    }

    /* Extract and separate the CbCr planes */
    size_t cbCrStride = mSurface->GetBytesPerRow(1);
    size_t cbCrWidth = mSurface->GetDevicePixelWidth(1);
    size_t cbCrHeight = mSurface->GetDevicePixelHeight(1);

    nsAutoArrayPtr<uint8_t> cbPlane(new uint8_t[cbCrWidth * cbCrHeight]);
    nsAutoArrayPtr<uint8_t> crPlane(new uint8_t[cbCrWidth * cbCrHeight]);

    uint8_t* src = (uint8_t*)mSurface->GetBaseAddressOfPlane(1);
    uint8_t* cbDest = cbPlane;
    uint8_t* crDest = crPlane;

    for (size_t i = 0; i < cbCrHeight; i++) {
      uint8_t* rowSrc = src + cbCrStride * i;
      for (size_t j = 0; j < cbCrWidth; j++) {
        *cbDest = *rowSrc;
        cbDest++;
        rowSrc++;
        *crDest = *rowSrc;
        crDest++;
        rowSrc++;
      }
    }

    /* Convert to RGB */
    PlanarYCbCrData data;
    data.mYChannel = (uint8_t*)mSurface->GetBaseAddressOfPlane(0);
    data.mYStride = mSurface->GetBytesPerRow(0);
    data.mYSize = IntSize(mSurface->GetDevicePixelWidth(0), mSurface->GetDevicePixelHeight(0));
    data.mCbChannel = cbPlane;
    data.mCrChannel = crPlane;
    data.mCbCrStride = cbCrWidth;
    data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
    data.mPicSize = data.mYSize;

    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
  } else {
    unsigned char* ioData = (unsigned char*)mSurface->GetBaseAddress();

    for (size_t i = 0; i < ioHeight; ++i) {
      memcpy(mappedSurface.mData + i * mappedSurface.mStride,
             ioData + i * bytesPerRow,
             ioWidth * 4);
    }
  }

  dataSurface->Unmap();
  mSurface->Unlock();

  return dataSurface.forget();
}