1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FramebufferNULL.cpp:
7 //    Implements the class methods for FramebufferNULL.
8 //
9 
10 #include "libANGLE/renderer/null/FramebufferNULL.h"
11 
12 #include "common/debug.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/formatutils.h"
15 #include "libANGLE/renderer/null/BufferNULL.h"
16 #include "libANGLE/renderer/null/ContextNULL.h"
17 
18 namespace rx
19 {
20 
FramebufferNULL(const gl::FramebufferState & state)21 FramebufferNULL::FramebufferNULL(const gl::FramebufferState &state) : FramebufferImpl(state) {}
22 
~FramebufferNULL()23 FramebufferNULL::~FramebufferNULL() {}
24 
discard(const gl::Context * context,size_t count,const GLenum * attachments)25 angle::Result FramebufferNULL::discard(const gl::Context *context,
26                                        size_t count,
27                                        const GLenum *attachments)
28 {
29     return angle::Result::Continue;
30 }
31 
invalidate(const gl::Context * context,size_t count,const GLenum * attachments)32 angle::Result FramebufferNULL::invalidate(const gl::Context *context,
33                                           size_t count,
34                                           const GLenum *attachments)
35 {
36     return angle::Result::Continue;
37 }
38 
invalidateSub(const gl::Context * context,size_t count,const GLenum * attachments,const gl::Rectangle & area)39 angle::Result FramebufferNULL::invalidateSub(const gl::Context *context,
40                                              size_t count,
41                                              const GLenum *attachments,
42                                              const gl::Rectangle &area)
43 {
44     return angle::Result::Continue;
45 }
46 
clear(const gl::Context * context,GLbitfield mask)47 angle::Result FramebufferNULL::clear(const gl::Context *context, GLbitfield mask)
48 {
49     return angle::Result::Continue;
50 }
51 
clearBufferfv(const gl::Context * context,GLenum buffer,GLint drawbuffer,const GLfloat * values)52 angle::Result FramebufferNULL::clearBufferfv(const gl::Context *context,
53                                              GLenum buffer,
54                                              GLint drawbuffer,
55                                              const GLfloat *values)
56 {
57     return angle::Result::Continue;
58 }
59 
clearBufferuiv(const gl::Context * context,GLenum buffer,GLint drawbuffer,const GLuint * values)60 angle::Result FramebufferNULL::clearBufferuiv(const gl::Context *context,
61                                               GLenum buffer,
62                                               GLint drawbuffer,
63                                               const GLuint *values)
64 {
65     return angle::Result::Continue;
66 }
67 
clearBufferiv(const gl::Context * context,GLenum buffer,GLint drawbuffer,const GLint * values)68 angle::Result FramebufferNULL::clearBufferiv(const gl::Context *context,
69                                              GLenum buffer,
70                                              GLint drawbuffer,
71                                              const GLint *values)
72 {
73     return angle::Result::Continue;
74 }
75 
clearBufferfi(const gl::Context * context,GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)76 angle::Result FramebufferNULL::clearBufferfi(const gl::Context *context,
77                                              GLenum buffer,
78                                              GLint drawbuffer,
79                                              GLfloat depth,
80                                              GLint stencil)
81 {
82     return angle::Result::Continue;
83 }
84 
readPixels(const gl::Context * context,const gl::Rectangle & origArea,GLenum format,GLenum type,const gl::PixelPackState & pack,gl::Buffer * packBuffer,void * ptrOrOffset)85 angle::Result FramebufferNULL::readPixels(const gl::Context *context,
86                                           const gl::Rectangle &origArea,
87                                           GLenum format,
88                                           GLenum type,
89                                           const gl::PixelPackState &pack,
90                                           gl::Buffer *packBuffer,
91                                           void *ptrOrOffset)
92 {
93     // Get the pointer to write to from the argument or the pack buffer
94     GLubyte *pixels = nullptr;
95     if (packBuffer != nullptr)
96     {
97         BufferNULL *packBufferGL = GetImplAs<BufferNULL>(packBuffer);
98         pixels                   = reinterpret_cast<GLubyte *>(packBufferGL->getDataPtr());
99         pixels += reinterpret_cast<intptr_t>(ptrOrOffset);
100     }
101     else
102     {
103         pixels = reinterpret_cast<GLubyte *>(ptrOrOffset);
104     }
105 
106     // Clip read area to framebuffer.
107     const gl::Extents fbSize = getState().getReadPixelsAttachment(format)->getSize();
108     const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
109     gl::Rectangle area;
110     if (!ClipRectangle(origArea, fbRect, &area))
111     {
112         // nothing to read
113         return angle::Result::Continue;
114     }
115 
116     // Compute size of unclipped rows and initial skip
117     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
118 
119     ContextNULL *contextNull = GetImplAs<ContextNULL>(context);
120 
121     GLuint rowBytes = 0;
122     ANGLE_CHECK_GL_MATH(contextNull, glFormat.computeRowPitch(type, origArea.width, pack.alignment,
123                                                               pack.rowLength, &rowBytes));
124 
125     GLuint skipBytes = 0;
126     ANGLE_CHECK_GL_MATH(contextNull,
127                         glFormat.computeSkipBytes(type, rowBytes, 0, pack, false, &skipBytes));
128     pixels += skipBytes;
129 
130     // Skip OOB region up to first in bounds pixel
131     int leftClip = area.x - origArea.x;
132     int topClip  = area.y - origArea.y;
133     pixels += leftClip * glFormat.pixelBytes + topClip * rowBytes;
134 
135     // Write the in-bounds readpixels data with non-zero values
136     for (GLint y = area.y; y < area.y + area.height; ++y)
137     {
138         memset(pixels, 42, glFormat.pixelBytes * area.width);
139         pixels += rowBytes;
140     }
141 
142     return angle::Result::Continue;
143 }
144 
blit(const gl::Context * context,const gl::Rectangle & sourceArea,const gl::Rectangle & destArea,GLbitfield mask,GLenum filter)145 angle::Result FramebufferNULL::blit(const gl::Context *context,
146                                     const gl::Rectangle &sourceArea,
147                                     const gl::Rectangle &destArea,
148                                     GLbitfield mask,
149                                     GLenum filter)
150 {
151     return angle::Result::Continue;
152 }
153 
checkStatus(const gl::Context * context) const154 gl::FramebufferStatus FramebufferNULL::checkStatus(const gl::Context *context) const
155 {
156     return gl::FramebufferStatus::Complete();
157 }
158 
syncState(const gl::Context * context,GLenum binding,const gl::Framebuffer::DirtyBits & dirtyBits,gl::Command command)159 angle::Result FramebufferNULL::syncState(const gl::Context *context,
160                                          GLenum binding,
161                                          const gl::Framebuffer::DirtyBits &dirtyBits,
162                                          gl::Command command)
163 {
164     return angle::Result::Continue;
165 }
166 
getSamplePosition(const gl::Context * context,size_t index,GLfloat * xy) const167 angle::Result FramebufferNULL::getSamplePosition(const gl::Context *context,
168                                                  size_t index,
169                                                  GLfloat *xy) const
170 {
171     return angle::Result::Continue;
172 }
173 
174 }  // namespace rx
175