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