Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/webrender_bindings/RenderBufferTextureHost.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "RenderBufferTextureHost.h"
8
9
#include "mozilla/gfx/Logging.h"
10
#include "mozilla/layers/ImageDataSerializer.h"
11
12
namespace mozilla {
13
namespace wr {
14
15
RenderBufferTextureHost::RenderBufferTextureHost(uint8_t* aBuffer,
16
                                                 const layers::BufferDescriptor& aDescriptor)
17
  : mBuffer(aBuffer)
18
  , mDescriptor(aDescriptor)
19
  , mMap()
20
  , mYMap()
21
  , mCbMap()
22
  , mCrMap()
23
  , mLocked(false)
24
0
{
25
0
  MOZ_COUNT_CTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
26
0
27
0
  switch (mDescriptor.type()) {
28
0
    case layers::BufferDescriptor::TYCbCrDescriptor: {
29
0
      const layers::YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
30
0
      mSize = ycbcr.ySize();
31
0
      mFormat = gfx::SurfaceFormat::YUV;
32
0
      break;
33
0
    }
34
0
    case layers::BufferDescriptor::TRGBDescriptor: {
35
0
      const layers::RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
36
0
      mSize = rgb.size();
37
0
      mFormat = rgb.format();
38
0
      break;
39
0
    }
40
0
    default:
41
0
      gfxCriticalError() << "Bad buffer host descriptor " << (int)mDescriptor.type();
42
0
      MOZ_CRASH("GFX: Bad descriptor");
43
0
  }
44
0
}
45
46
RenderBufferTextureHost::~RenderBufferTextureHost()
47
0
{
48
0
  MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
49
0
}
50
51
wr::WrExternalImage
52
RenderBufferTextureHost::Lock(uint8_t aChannelIndex,
53
                              gl::GLContext* aGL,
54
                              wr::ImageRendering aRendering)
55
0
{
56
0
  if (!mLocked) {
57
0
    if (!GetBuffer()) {
58
0
      // We hit some problems to get the shmem.
59
0
      return InvalidToWrExternalImage();
60
0
    }
61
0
    if (mFormat != gfx::SurfaceFormat::YUV) {
62
0
      mSurface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
63
0
                                                               layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
64
0
                                                               mSize,
65
0
                                                               mFormat);
66
0
      if (NS_WARN_IF(!mSurface)) {
67
0
        return InvalidToWrExternalImage();
68
0
      }
69
0
      if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
70
0
        mSurface = nullptr;
71
0
        return InvalidToWrExternalImage();
72
0
      }
73
0
    } else {
74
0
      const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
75
0
76
0
      mYSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
77
0
                                                                desc.yStride(),
78
0
                                                                desc.ySize(),
79
0
                                                                gfx::SurfaceFormat::A8);
80
0
      mCbSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc),
81
0
                                                                 desc.cbCrStride(),
82
0
                                                                 desc.cbCrSize(),
83
0
                                                                 gfx::SurfaceFormat::A8);
84
0
      mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
85
0
                                                                 desc.cbCrStride(),
86
0
                                                                 desc.cbCrSize(),
87
0
                                                                 gfx::SurfaceFormat::A8);
88
0
      if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
89
0
        mYSurface = mCbSurface = mCrSurface = nullptr;
90
0
        return InvalidToWrExternalImage();
91
0
      }
92
0
      if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
93
0
                     !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||
94
0
                     !mCrSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCrMap))) {
95
0
        mYSurface = mCbSurface = mCrSurface = nullptr;
96
0
        return InvalidToWrExternalImage();
97
0
      }
98
0
    }
99
0
    mLocked = true;
100
0
  }
101
0
102
0
  RenderBufferData data = GetBufferDataForRender(aChannelIndex);
103
0
  return RawDataToWrExternalImage(data.mData, data.mBufferSize);
104
0
}
105
106
void
107
RenderBufferTextureHost::Unlock()
108
0
{
109
0
  if (mLocked) {
110
0
    if (mSurface) {
111
0
      mSurface->Unmap();
112
0
      mSurface = nullptr;
113
0
    } else if (mYSurface) {
114
0
      mYSurface->Unmap();
115
0
      mCbSurface->Unmap();
116
0
      mCrSurface->Unmap();
117
0
      mYSurface = mCbSurface = mCrSurface = nullptr;
118
0
    }
119
0
    mLocked = false;
120
0
  }
121
0
}
122
123
RenderBufferTextureHost::RenderBufferData
124
RenderBufferTextureHost::GetBufferDataForRender(uint8_t aChannelIndex)
125
0
{
126
0
  MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV || aChannelIndex < 3);
127
0
  MOZ_ASSERT(mFormat == gfx::SurfaceFormat::YUV || aChannelIndex < 1);
128
0
  MOZ_ASSERT(mLocked);
129
0
130
0
  if (mFormat != gfx::SurfaceFormat::YUV) {
131
0
    MOZ_ASSERT(mSurface);
132
0
133
0
    return RenderBufferData(mMap.mData, mMap.mStride * mSurface->GetSize().height);
134
0
  } else {
135
0
    MOZ_ASSERT(mYSurface && mCbSurface && mCrSurface);
136
0
137
0
    switch (aChannelIndex) {
138
0
      case 0:
139
0
        return RenderBufferData(mYMap.mData, mYMap.mStride * mYSurface->GetSize().height);
140
0
        break;
141
0
      case 1:
142
0
        return RenderBufferData(mCbMap.mData, mCbMap.mStride * mCbSurface->GetSize().height);
143
0
        break;
144
0
      case 2:
145
0
        return RenderBufferData(mCrMap.mData, mCrMap.mStride * mCrSurface->GetSize().height);
146
0
        break;
147
0
      default:
148
0
        MOZ_ASSERT_UNREACHABLE("unexpected to be called");
149
0
        return RenderBufferData(nullptr, 0);
150
0
    }
151
0
  }
152
0
}
153
154
} // namespace wr
155
} // namespace mozilla