OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 #include <string> | 10 #include <string> |
11 #include <map> | 11 #include <map> |
12 #include <build/build_config.h> | 12 #include <build/build_config.h> |
13 #include "base/scoped_ptr.h" | 13 #include "base/scoped_ptr.h" |
14 #define GLES2_GPU_SERVICE 1 | 14 #define GLES2_GPU_SERVICE 1 |
15 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 15 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
16 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 16 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
17 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 17 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
18 #include "gpu/command_buffer/service/gl_utils.h" | 18 #include "gpu/command_buffer/service/gl_utils.h" |
19 #include "gpu/command_buffer/service/gles2_cmd_validation.h" | 19 #include "gpu/command_buffer/service/gles2_cmd_validation.h" |
20 #if defined(OS_LINUX) && !defined(UNIT_TEST) | 20 #if defined(UNIT_TEST) |
| 21 #elif defined(OS_LINUX) |
21 // XWindowWrapper is stubbed out for unit-tests. | 22 // XWindowWrapper is stubbed out for unit-tests. |
22 #include "gpu/command_buffer/service/x_utils.h" | 23 #include "gpu/command_buffer/service/x_utils.h" |
| 24 #elif defined(OS_MACOSX) |
| 25 // The following two #includes CAN NOT go above the inclusion of |
| 26 // gl_utils.h and therefore glew.h regardless of what the Google C++ |
| 27 // style guide says. |
| 28 #include <CoreFoundation/CoreFoundation.h> // NOLINT |
| 29 #include <OpenGL/OpenGL.h> // NOLINT |
| 30 #include "base/scoped_cftyperef.h" |
| 31 #include "chrome/common/io_surface_support_mac.h" |
23 #endif | 32 #endif |
24 | 33 |
25 namespace gpu { | 34 namespace gpu { |
26 namespace gles2 { | 35 namespace gles2 { |
27 | 36 |
28 // Check that certain assumptions the code makes are true. There are places in | 37 // Check that certain assumptions the code makes are true. There are places in |
29 // the code where shared memory is passed direclty to GL. Example, glUniformiv, | 38 // the code where shared memory is passed direclty to GL. Example, glUniformiv, |
30 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe | 39 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe |
31 // a few others) are 32bits. If they are not 32bits the code will have to change | 40 // a few others) are 32bits. If they are not 32bits the code will have to change |
32 // to call those GL functions with service side memory and then copy the results | 41 // to call those GL functions with service side memory and then copy the results |
33 // to shared memory, converting the sizes. | 42 // to shared memory, converting the sizes. |
34 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT | 43 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT |
35 GLint_not_same_size_as_uint32); | 44 GLint_not_same_size_as_uint32); |
36 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT | 45 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT |
37 GLint_not_same_size_as_uint32); | 46 GLint_not_same_size_as_uint32); |
38 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT | 47 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT |
39 GLfloat_not_same_size_as_float); | 48 GLfloat_not_same_size_as_float); |
40 | 49 |
41 namespace { | 50 // TODO(kbr): the use of this anonymous namespace core dumps the |
| 51 // linker on Mac OS X 10.6 when the symbol ordering file is used |
| 52 // namespace { |
42 | 53 |
43 size_t GetGLTypeSize(GLenum type) { | 54 static size_t GetGLTypeSize(GLenum type) { |
44 switch (type) { | 55 switch (type) { |
45 case GL_BYTE: | 56 case GL_BYTE: |
46 return sizeof(GLbyte); // NOLINT | 57 return sizeof(GLbyte); // NOLINT |
47 case GL_UNSIGNED_BYTE: | 58 case GL_UNSIGNED_BYTE: |
48 return sizeof(GLubyte); // NOLINT | 59 return sizeof(GLubyte); // NOLINT |
49 case GL_SHORT: | 60 case GL_SHORT: |
50 return sizeof(GLshort); // NOLINT | 61 return sizeof(GLshort); // NOLINT |
51 case GL_UNSIGNED_SHORT: | 62 case GL_UNSIGNED_SHORT: |
52 return sizeof(GLushort); // NOLINT | 63 return sizeof(GLushort); // NOLINT |
53 case GL_FLOAT: | 64 case GL_FLOAT: |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 case GLErrorBit::kOutOfMemory: | 151 case GLErrorBit::kOutOfMemory: |
141 return GL_OUT_OF_MEMORY; | 152 return GL_OUT_OF_MEMORY; |
142 case GLErrorBit::kInvalidFrameBufferOperation: | 153 case GLErrorBit::kInvalidFrameBufferOperation: |
143 return GL_INVALID_FRAMEBUFFER_OPERATION; | 154 return GL_INVALID_FRAMEBUFFER_OPERATION; |
144 default: | 155 default: |
145 DCHECK(false); | 156 DCHECK(false); |
146 return GL_NO_ERROR; | 157 return GL_NO_ERROR; |
147 } | 158 } |
148 } | 159 } |
149 | 160 |
150 } // anonymous namespace. | 161 // } // anonymous namespace. |
151 | 162 |
152 #if defined(UNIT_TEST) | 163 #if defined(UNIT_TEST) |
153 GLES2Decoder::GLES2Decoder() | 164 GLES2Decoder::GLES2Decoder() |
154 : debug_(false) { | 165 : debug_(false) { |
155 #elif defined(OS_LINUX) | 166 #elif defined(OS_LINUX) |
156 GLES2Decoder::GLES2Decoder() | 167 GLES2Decoder::GLES2Decoder() |
157 : debug_(false), | 168 : debug_(false), |
158 window_(NULL) { | 169 window_(NULL) { |
159 #elif defined(OS_WIN) | 170 #elif defined(OS_WIN) |
160 GLES2Decoder::GLES2Decoder() | 171 GLES2Decoder::GLES2Decoder() |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 555 |
545 // Overridden from AsyncAPIInterface. | 556 // Overridden from AsyncAPIInterface. |
546 virtual const char* GetCommandName(unsigned int command_id) const; | 557 virtual const char* GetCommandName(unsigned int command_id) const; |
547 | 558 |
548 // Overridden from GLES2Decoder. | 559 // Overridden from GLES2Decoder. |
549 virtual bool Initialize(); | 560 virtual bool Initialize(); |
550 virtual void Destroy(); | 561 virtual void Destroy(); |
551 virtual bool MakeCurrent(); | 562 virtual bool MakeCurrent(); |
552 virtual uint32 GetServiceIdForTesting(uint32 client_id); | 563 virtual uint32 GetServiceIdForTesting(uint32 client_id); |
553 | 564 |
| 565 #if !defined(UNIT_TEST) && defined(OS_MACOSX) |
| 566 // Overridden from GLES2Decoder. |
| 567 virtual uint64 SetWindowSize(int32 width, int32 height); |
| 568 #endif |
| 569 |
| 570 virtual void SetSwapBuffersCallback(Callback0::Type* callback); |
| 571 |
554 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used | 572 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used |
555 // on glDeleteBuffers so we can make sure the user does not try to render | 573 // on glDeleteBuffers so we can make sure the user does not try to render |
556 // with deleted buffers. | 574 // with deleted buffers. |
557 void RemoveBufferInfo(GLuint buffer_id); | 575 void RemoveBufferInfo(GLuint buffer_id); |
558 | 576 |
559 private: | 577 private: |
560 bool InitPlatformSpecific(); | 578 bool InitPlatformSpecific(); |
561 bool InitGlew(); | 579 bool InitGlew(); |
562 | 580 |
563 // Template to help call glGenXXX functions. | 581 // Template to help call glGenXXX functions. |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 | 740 |
723 scoped_ptr<ProgramManager> program_manager_; | 741 scoped_ptr<ProgramManager> program_manager_; |
724 | 742 |
725 // The program in use by glUseProgram | 743 // The program in use by glUseProgram |
726 GLuint current_program_; | 744 GLuint current_program_; |
727 | 745 |
728 #if defined(UNIT_TEST) | 746 #if defined(UNIT_TEST) |
729 #elif defined(OS_WIN) | 747 #elif defined(OS_WIN) |
730 HDC device_context_; | 748 HDC device_context_; |
731 HGLRC gl_context_; | 749 HGLRC gl_context_; |
| 750 #elif defined(OS_MACOSX) |
| 751 CGLContextObj gl_context_; |
| 752 CGLPBufferObj pbuffer_; |
| 753 scoped_cftyperef<CFTypeRef> io_surface_; |
| 754 int32 surface_width_; |
| 755 int32 surface_height_; |
| 756 GLuint texture_; |
| 757 GLuint fbo_; |
| 758 GLuint depth_renderbuffer_; |
| 759 // For tracking whether the default framebuffer / renderbuffer or |
| 760 // ones created by the end user are currently bound |
| 761 GLuint bound_fbo_; |
| 762 GLuint bound_renderbuffer_; |
732 #endif | 763 #endif |
733 | 764 |
734 bool anti_aliased_; | 765 bool anti_aliased_; |
735 | 766 |
| 767 scoped_ptr<Callback0::Type> swap_buffers_callback_; |
| 768 |
736 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 769 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
737 }; | 770 }; |
738 | 771 |
739 GLES2Decoder* GLES2Decoder::Create() { | 772 GLES2Decoder* GLES2Decoder::Create() { |
740 return new GLES2DecoderImpl(); | 773 return new GLES2DecoderImpl(); |
741 } | 774 } |
742 | 775 |
743 GLES2DecoderImpl::GLES2DecoderImpl() | 776 GLES2DecoderImpl::GLES2DecoderImpl() |
744 : GLES2Decoder(), | 777 : GLES2Decoder(), |
745 error_bits_(0), | 778 error_bits_(0), |
746 util_(0), // TODO(gman): Set to actual num compress texture formats. | 779 util_(0), // TODO(gman): Set to actual num compress texture formats. |
747 pack_alignment_(4), | 780 pack_alignment_(4), |
748 unpack_alignment_(4), | 781 unpack_alignment_(4), |
749 bound_array_buffer_(0), | 782 bound_array_buffer_(0), |
750 bound_element_array_buffer_(0), | 783 bound_element_array_buffer_(0), |
751 max_vertex_attribs_(0), | 784 max_vertex_attribs_(0), |
752 current_program_(0), | 785 current_program_(0), |
753 #if defined(UNIT_TEST) | 786 #if defined(UNIT_TEST) |
754 #elif defined(OS_WIN) | 787 #elif defined(OS_WIN) |
755 device_context_(NULL), | 788 device_context_(NULL), |
756 gl_context_(NULL), | 789 gl_context_(NULL), |
| 790 #elif defined(OS_MACOSX) |
| 791 gl_context_(NULL), |
| 792 pbuffer_(NULL), |
| 793 surface_width_(0), |
| 794 surface_height_(0), |
| 795 texture_(0), |
| 796 fbo_(0), |
| 797 depth_renderbuffer_(0), |
| 798 bound_fbo_(0), |
| 799 bound_renderbuffer_(0), |
757 #endif | 800 #endif |
758 anti_aliased_(false) { | 801 anti_aliased_(false) { |
759 } | 802 } |
760 | 803 |
761 bool GLES2DecoderImpl::Initialize() { | 804 bool GLES2DecoderImpl::Initialize() { |
762 bool success = false; | 805 bool success = false; |
763 | 806 |
764 id_manager_.reset(new IdManager()); | 807 id_manager_.reset(new IdManager()); |
765 buffer_manager_.reset(new BufferManager()); | 808 buffer_manager_.reset(new BufferManager()); |
766 program_manager_.reset(new ProgramManager()); | 809 program_manager_.reset(new ProgramManager()); |
(...skipping 16 matching lines...) Expand all Loading... |
783 | 826 |
784 // glBindFramebuffer(0, 0); | 827 // glBindFramebuffer(0, 0); |
785 success = true; | 828 success = true; |
786 } | 829 } |
787 } | 830 } |
788 } | 831 } |
789 | 832 |
790 return success; | 833 return success; |
791 } | 834 } |
792 | 835 |
793 namespace { | 836 // TODO(kbr): the use of this anonymous namespace core dumps the |
| 837 // linker on Mac OS X 10.6 when the symbol ordering file is used |
| 838 // namespace { |
794 | 839 |
795 #if defined(UNIT_TEST) | 840 #if defined(UNIT_TEST) |
796 #elif defined(OS_WIN) | 841 #elif defined(OS_WIN) |
797 | 842 |
798 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { | 843 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { |
799 sizeof(kPixelFormatDescriptor), // Size of structure. | 844 sizeof(kPixelFormatDescriptor), // Size of structure. |
800 1, // Default version. | 845 1, // Default version. |
801 PFD_DRAW_TO_WINDOW | // Window drawing support. | 846 PFD_DRAW_TO_WINDOW | // Window drawing support. |
802 PFD_SUPPORT_OPENGL | // OpenGL support. | 847 PFD_SUPPORT_OPENGL | // OpenGL support. |
803 PFD_DOUBLEBUFFER, // Double buffering support (not stereo). | 848 PFD_DOUBLEBUFFER, // Double buffering support (not stereo). |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 void GLDeleteRenderbuffersHelper( | 1045 void GLDeleteRenderbuffersHelper( |
1001 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { | 1046 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { |
1002 glDeleteRenderbuffersEXT(n, ids); | 1047 glDeleteRenderbuffersEXT(n, ids); |
1003 } | 1048 } |
1004 | 1049 |
1005 void GLDeleteTexturesHelper( | 1050 void GLDeleteTexturesHelper( |
1006 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { | 1051 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { |
1007 glDeleteTextures(n, ids); | 1052 glDeleteTextures(n, ids); |
1008 } | 1053 } |
1009 | 1054 |
1010 } // anonymous namespace | 1055 // } // anonymous namespace |
1011 | 1056 |
1012 bool GLES2DecoderImpl::MakeCurrent() { | 1057 bool GLES2DecoderImpl::MakeCurrent() { |
1013 #if defined(UNIT_TEST) | 1058 #if defined(UNIT_TEST) |
1014 return true; | 1059 return true; |
1015 #elif defined(OS_WIN) | 1060 #elif defined(OS_WIN) |
1016 if (::wglGetCurrentDC() == device_context_ && | 1061 if (::wglGetCurrentDC() == device_context_ && |
1017 ::wglGetCurrentContext() == gl_context_) { | 1062 ::wglGetCurrentContext() == gl_context_) { |
1018 return true; | 1063 return true; |
1019 } | 1064 } |
1020 if (!::wglMakeCurrent(device_context_, gl_context_)) { | 1065 if (!::wglMakeCurrent(device_context_, gl_context_)) { |
1021 DLOG(ERROR) << "Unable to make gl context current."; | 1066 DLOG(ERROR) << "Unable to make gl context current."; |
1022 return false; | 1067 return false; |
1023 } | 1068 } |
1024 return true; | 1069 return true; |
1025 #elif defined(OS_LINUX) | 1070 #elif defined(OS_LINUX) |
1026 return window()->MakeCurrent(); | 1071 return window()->MakeCurrent(); |
| 1072 #elif defined(OS_MACOSX) |
| 1073 if (CGLGetCurrentContext() != gl_context_) { |
| 1074 if (CGLSetCurrentContext(gl_context_) != kCGLNoError) { |
| 1075 DLOG(ERROR) << "Unable to make gl context current."; |
| 1076 return false; |
| 1077 } |
| 1078 } |
| 1079 return true; |
1027 #else | 1080 #else |
1028 NOTREACHED(); | 1081 NOTREACHED(); |
1029 return false; | 1082 return false; |
1030 #endif | 1083 #endif |
1031 } | 1084 } |
1032 | 1085 |
1033 uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) { | 1086 uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) { |
1034 #if defined(UNIT_TEST) | 1087 #if defined(UNIT_TEST) |
1035 GLuint service_id; | 1088 GLuint service_id; |
1036 bool result = id_manager_->GetServiceId(client_id, &service_id); | 1089 bool result = id_manager_->GetServiceId(client_id, &service_id); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1149 |
1097 gl_context_ = ::wglCreateContext(device_context_); | 1150 gl_context_ = ::wglCreateContext(device_context_); |
1098 if (!gl_context_) { | 1151 if (!gl_context_) { |
1099 DLOG(ERROR) << "Failed to create GL context."; | 1152 DLOG(ERROR) << "Failed to create GL context."; |
1100 return false; | 1153 return false; |
1101 } | 1154 } |
1102 #elif defined(OS_LINUX) | 1155 #elif defined(OS_LINUX) |
1103 DCHECK(window()); | 1156 DCHECK(window()); |
1104 if (!window()->Initialize()) | 1157 if (!window()->Initialize()) |
1105 return false; | 1158 return false; |
| 1159 #elif defined(OS_MACOSX) |
| 1160 // Create a 1x1 pbuffer and associated context to bootstrap things |
| 1161 static const CGLPixelFormatAttribute attribs[] = { |
| 1162 (CGLPixelFormatAttribute) kCGLPFAPBuffer, |
| 1163 (CGLPixelFormatAttribute) 0 |
| 1164 }; |
| 1165 CGLPixelFormatObj pixelFormat; |
| 1166 GLint numPixelFormats; |
| 1167 if (CGLChoosePixelFormat(attribs, |
| 1168 &pixelFormat, |
| 1169 &numPixelFormats) != kCGLNoError) { |
| 1170 DLOG(ERROR) << "Error choosing pixel format."; |
| 1171 return false; |
| 1172 } |
| 1173 if (!pixelFormat) { |
| 1174 return false; |
| 1175 } |
| 1176 CGLContextObj context; |
| 1177 CGLError res = CGLCreateContext(pixelFormat, 0, &context); |
| 1178 CGLDestroyPixelFormat(pixelFormat); |
| 1179 if (res != kCGLNoError) { |
| 1180 DLOG(ERROR) << "Error creating context."; |
| 1181 return false; |
| 1182 } |
| 1183 CGLPBufferObj pbuffer; |
| 1184 if (CGLCreatePBuffer(1, 1, |
| 1185 GL_TEXTURE_2D, GL_RGBA, |
| 1186 0, &pbuffer) != kCGLNoError) { |
| 1187 CGLDestroyContext(context); |
| 1188 DLOG(ERROR) << "Error creating pbuffer."; |
| 1189 return false; |
| 1190 } |
| 1191 if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { |
| 1192 CGLDestroyContext(context); |
| 1193 CGLDestroyPBuffer(pbuffer); |
| 1194 DLOG(ERROR) << "Error attaching pbuffer to context."; |
| 1195 return false; |
| 1196 } |
| 1197 gl_context_ = context; |
| 1198 pbuffer_ = pbuffer; |
| 1199 // Now we're ready to handle SetWindowSize calls, which will |
| 1200 // allocate and/or reallocate the IOSurface and associated offscreen |
| 1201 // OpenGL structures for rendering. |
1106 #endif | 1202 #endif |
1107 | 1203 |
1108 return true; | 1204 return true; |
1109 } | 1205 } |
1110 | 1206 |
1111 bool GLES2DecoderImpl::InitGlew() { | 1207 bool GLES2DecoderImpl::InitGlew() { |
1112 #if !defined(UNIT_TEST) | 1208 #if !defined(UNIT_TEST) |
1113 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; | 1209 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; |
1114 | 1210 |
1115 GLenum glew_error = glewInit(); | 1211 GLenum glew_error = glewInit(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 DLOG(ERROR) << "Separate blend function extension missing."; | 1253 DLOG(ERROR) << "Separate blend function extension missing."; |
1158 extensions_found = false; | 1254 extensions_found = false; |
1159 } | 1255 } |
1160 if (!extensions_found) | 1256 if (!extensions_found) |
1161 return false; | 1257 return false; |
1162 #endif | 1258 #endif |
1163 | 1259 |
1164 return true; | 1260 return true; |
1165 } | 1261 } |
1166 | 1262 |
| 1263 #if !defined(UNIT_TEST) && defined(OS_MACOSX) |
| 1264 static void AddBooleanValue(CFMutableDictionaryRef dictionary, |
| 1265 const CFStringRef key, |
| 1266 bool value) { |
| 1267 CFDictionaryAddValue(dictionary, key, |
| 1268 (value ? kCFBooleanTrue : kCFBooleanFalse)); |
| 1269 } |
| 1270 |
| 1271 static void AddIntegerValue(CFMutableDictionaryRef dictionary, |
| 1272 const CFStringRef key, |
| 1273 int32 value) { |
| 1274 CFNumberRef number = CFNumberCreate(NULL, kCFNumberSInt32Type, &value); |
| 1275 CFDictionaryAddValue(dictionary, key, number); |
| 1276 } |
| 1277 |
| 1278 uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) { |
| 1279 if (surface_width_ == width && surface_height_ == height) { |
| 1280 // Return 0 to indicate to the caller that no new backing store |
| 1281 // allocation occurred. |
| 1282 return 0; |
| 1283 } |
| 1284 |
| 1285 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); |
| 1286 if (!io_surface_support) |
| 1287 return 0; |
| 1288 |
| 1289 if (!MakeCurrent()) |
| 1290 return 0; |
| 1291 |
| 1292 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on |
| 1293 // Mac OS X and is required for IOSurface interoperability. |
| 1294 GLenum target = GL_TEXTURE_RECTANGLE_ARB; |
| 1295 |
| 1296 if (!texture_) { |
| 1297 // Generate the texture object. |
| 1298 glGenTextures(1, &texture_); |
| 1299 glBindTexture(target, texture_); |
| 1300 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 1301 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 1302 // Generate and bind the framebuffer object. |
| 1303 glGenFramebuffersEXT(1, &fbo_); |
| 1304 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); |
| 1305 bound_fbo_ = fbo_; |
| 1306 // Generate (but don't bind) the depth buffer -- we don't need |
| 1307 // this bound in order to do offscreen rendering. |
| 1308 glGenRenderbuffersEXT(1, &depth_renderbuffer_); |
| 1309 } |
| 1310 |
| 1311 // Allocate a new IOSurface, which is the GPU resource that can be |
| 1312 // shared across processes. |
| 1313 scoped_cftyperef<CFMutableDictionaryRef> properties; |
| 1314 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 1315 0, |
| 1316 &kCFTypeDictionaryKeyCallBacks, |
| 1317 &kCFTypeDictionaryValueCallBacks)); |
| 1318 AddIntegerValue(properties, |
| 1319 io_surface_support->GetKIOSurfaceWidth(), width); |
| 1320 AddIntegerValue(properties, |
| 1321 io_surface_support->GetKIOSurfaceHeight(), height); |
| 1322 AddIntegerValue(properties, |
| 1323 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); |
| 1324 AddBooleanValue(properties, |
| 1325 io_surface_support->GetKIOSurfaceIsGlobal(), true); |
| 1326 // I believe we should be able to unreference the IOSurfaces without |
| 1327 // synchronizing with the browser process because they are |
| 1328 // ultimately reference counted by the operating system. |
| 1329 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); |
| 1330 |
| 1331 // Reallocate the depth buffer. |
| 1332 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_renderbuffer_); |
| 1333 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, |
| 1334 GL_DEPTH_COMPONENT, |
| 1335 width, |
| 1336 height); |
| 1337 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, bound_renderbuffer_); |
| 1338 |
| 1339 // Reallocate the texture object. |
| 1340 glBindTexture(target, texture_); |
| 1341 // Don't think we need to identify a plane. |
| 1342 GLuint plane = 0; |
| 1343 io_surface_support->CGLTexImageIOSurface2D(gl_context_, |
| 1344 target, |
| 1345 GL_RGBA, |
| 1346 width, |
| 1347 height, |
| 1348 GL_BGRA, |
| 1349 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 1350 io_surface_.get(), |
| 1351 plane); |
| 1352 |
| 1353 // Set up the frame buffer object. |
| 1354 if (bound_fbo_ != fbo_) { |
| 1355 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); |
| 1356 } |
| 1357 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, |
| 1358 GL_COLOR_ATTACHMENT0_EXT, |
| 1359 target, |
| 1360 texture_, |
| 1361 0); |
| 1362 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, |
| 1363 GL_DEPTH_ATTACHMENT_EXT, |
| 1364 GL_RENDERBUFFER_EXT, |
| 1365 depth_renderbuffer_); |
| 1366 if (bound_fbo_ != fbo_) { |
| 1367 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); |
| 1368 } |
| 1369 |
| 1370 surface_width_ = width; |
| 1371 surface_height_ = height; |
| 1372 |
| 1373 // Now send back an identifier for the IOSurface. We originally |
| 1374 // intended to send back a mach port from IOSurfaceCreateMachPort |
| 1375 // but it looks like Chrome IPC would need to be modified to |
| 1376 // properly send mach ports between processes. For the time being we |
| 1377 // make our IOSurfaces global and send back their identifiers. On |
| 1378 // the browser process side the identifier is reconstituted into an |
| 1379 // IOSurface for on-screen rendering. |
| 1380 return io_surface_support->IOSurfaceGetID(io_surface_); |
| 1381 } |
| 1382 #endif // !defined(UNIT_TEST) && defined(OS_MACOSX) |
| 1383 |
| 1384 void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { |
| 1385 swap_buffers_callback_.reset(callback); |
| 1386 } |
| 1387 |
1167 void GLES2DecoderImpl::Destroy() { | 1388 void GLES2DecoderImpl::Destroy() { |
1168 #if defined(UNIT_TEST) | 1389 #if defined(UNIT_TEST) |
1169 #elif defined(OS_LINUX) | 1390 #elif defined(OS_LINUX) |
1170 DCHECK(window()); | 1391 DCHECK(window()); |
1171 window()->Destroy(); | 1392 window()->Destroy(); |
| 1393 #elif defined(OS_MACOSX) |
| 1394 if (gl_context_) |
| 1395 CGLDestroyContext(gl_context_); |
| 1396 if (pbuffer_) |
| 1397 CGLDestroyPBuffer(pbuffer_); |
1172 #endif | 1398 #endif |
1173 } | 1399 } |
1174 | 1400 |
1175 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { | 1401 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { |
1176 if (command_id > kStartPoint && command_id < kNumCommands) { | 1402 if (command_id > kStartPoint && command_id < kNumCommands) { |
1177 return gles2::GetCommandName(static_cast<CommandId>(command_id)); | 1403 return gles2::GetCommandName(static_cast<CommandId>(command_id)); |
1178 } | 1404 } |
1179 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); | 1405 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); |
1180 } | 1406 } |
1181 | 1407 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 | 1551 |
1326 // NOTE: If you need to know the results of SwapBuffers (like losing | 1552 // NOTE: If you need to know the results of SwapBuffers (like losing |
1327 // the context) then add a new command. Do NOT make SwapBuffers synchronous. | 1553 // the context) then add a new command. Do NOT make SwapBuffers synchronous. |
1328 void GLES2DecoderImpl::DoSwapBuffers() { | 1554 void GLES2DecoderImpl::DoSwapBuffers() { |
1329 #if defined(UNIT_TEST) | 1555 #if defined(UNIT_TEST) |
1330 #elif defined(OS_WIN) | 1556 #elif defined(OS_WIN) |
1331 ::SwapBuffers(device_context_); | 1557 ::SwapBuffers(device_context_); |
1332 #elif defined(OS_LINUX) | 1558 #elif defined(OS_LINUX) |
1333 DCHECK(window()); | 1559 DCHECK(window()); |
1334 window()->SwapBuffers(); | 1560 window()->SwapBuffers(); |
| 1561 #elif defined(OS_MACOSX) |
| 1562 if (bound_fbo_ == fbo_) { |
| 1563 // Bind and unbind the framebuffer to make changes to the |
| 1564 // IOSurface show up in the other process. |
| 1565 glFlush(); |
| 1566 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
| 1567 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); |
| 1568 } |
1335 #endif | 1569 #endif |
| 1570 if (swap_buffers_callback_.get()) { |
| 1571 swap_buffers_callback_->Run(); |
| 1572 } |
1336 } | 1573 } |
1337 | 1574 |
1338 void GLES2DecoderImpl::DoUseProgram(GLuint program) { | 1575 void GLES2DecoderImpl::DoUseProgram(GLuint program) { |
1339 ProgramManager::ProgramInfo* info = GetProgramInfo(program); | 1576 ProgramManager::ProgramInfo* info = GetProgramInfo(program); |
1340 if (!info) { | 1577 if (!info) { |
1341 // Program was not linked successfully. (ie, glLinkProgram) | 1578 // Program was not linked successfully. (ie, glLinkProgram) |
1342 SetGLError(GL_INVALID_OPERATION); | 1579 SetGLError(GL_INVALID_OPERATION); |
1343 } else { | 1580 } else { |
1344 current_program_ = program; | 1581 current_program_ = program; |
1345 glUseProgram(program); | 1582 glUseProgram(program); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1469 } | 1706 } |
1470 } | 1707 } |
1471 } | 1708 } |
1472 } | 1709 } |
1473 } else { | 1710 } else { |
1474 SetGLError(GL_INVALID_VALUE); | 1711 SetGLError(GL_INVALID_VALUE); |
1475 } | 1712 } |
1476 return error::kNoError; | 1713 return error::kNoError; |
1477 } | 1714 } |
1478 | 1715 |
1479 namespace { | 1716 // TODO(kbr): the use of this anonymous namespace core dumps the |
| 1717 // linker on Mac OS X 10.6 when the symbol ordering file is used |
| 1718 // namespace { |
1480 | 1719 |
1481 // Calls glShaderSource for the various versions of the ShaderSource command. | 1720 // Calls glShaderSource for the various versions of the ShaderSource command. |
1482 // Assumes that data / data_size points to a piece of memory that is in range | 1721 // Assumes that data / data_size points to a piece of memory that is in range |
1483 // of whatever context it came from (shared memory, immediate memory, bucket | 1722 // of whatever context it came from (shared memory, immediate memory, bucket |
1484 // memory.) | 1723 // memory.) |
1485 error::Error ShaderSourceHelper( | 1724 error::Error ShaderSourceHelper( |
1486 GLuint shader, GLsizei count, const char* data, uint32 data_size) { | 1725 GLuint shader, GLsizei count, const char* data, uint32 data_size) { |
1487 std::vector<std::string> strings(count); | 1726 std::vector<std::string> strings(count); |
1488 scoped_array<const char*> string_pointers(new const char* [count]); | 1727 scoped_array<const char*> string_pointers(new const char* [count]); |
1489 | 1728 |
1490 const uint32* ends = reinterpret_cast<const uint32*>(data); | 1729 const uint32* ends = reinterpret_cast<const uint32*>(data); |
1491 uint32 start_offset = count * sizeof(*ends); | 1730 uint32 start_offset = count * sizeof(*ends); |
1492 if (start_offset > data_size) { | 1731 if (start_offset > data_size) { |
1493 return error::kOutOfBounds; | 1732 return error::kOutOfBounds; |
1494 } | 1733 } |
1495 for (GLsizei ii = 0; ii < count; ++ii) { | 1734 for (GLsizei ii = 0; ii < count; ++ii) { |
1496 uint32 end_offset = ends[ii]; | 1735 uint32 end_offset = ends[ii]; |
1497 if (end_offset > data_size || end_offset < start_offset) { | 1736 if (end_offset > data_size || end_offset < start_offset) { |
1498 return error::kOutOfBounds; | 1737 return error::kOutOfBounds; |
1499 } | 1738 } |
1500 strings[ii] = std::string(data + start_offset, end_offset - start_offset); | 1739 strings[ii] = std::string(data + start_offset, end_offset - start_offset); |
1501 string_pointers[ii] = strings[ii].c_str(); | 1740 string_pointers[ii] = strings[ii].c_str(); |
1502 } | 1741 } |
1503 | 1742 |
1504 glShaderSource(shader, count, string_pointers.get(), NULL); | 1743 glShaderSource(shader, count, string_pointers.get(), NULL); |
1505 return error::kNoError; | 1744 return error::kNoError; |
1506 } | 1745 } |
1507 | 1746 |
1508 } // anonymous namespace. | 1747 // } // anonymous namespace. |
1509 | 1748 |
1510 error::Error GLES2DecoderImpl::HandleShaderSource( | 1749 error::Error GLES2DecoderImpl::HandleShaderSource( |
1511 uint32 immediate_data_size, const gles2::ShaderSource& c) { | 1750 uint32 immediate_data_size, const gles2::ShaderSource& c) { |
1512 GLuint shader; | 1751 GLuint shader; |
1513 if (!id_manager_->GetServiceId(c.shader, &shader)) { | 1752 if (!id_manager_->GetServiceId(c.shader, &shader)) { |
1514 SetGLError(GL_INVALID_VALUE); | 1753 SetGLError(GL_INVALID_VALUE); |
1515 return error::kNoError; | 1754 return error::kNoError; |
1516 } | 1755 } |
1517 GLsizei count = c.count; | 1756 GLsizei count = c.count; |
1518 uint32 data_size = c.data_size; | 1757 uint32 data_size = c.data_size; |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 return error::kNoError; | 2270 return error::kNoError; |
2032 } | 2271 } |
2033 | 2272 |
2034 // Include the auto-generated part of this file. We split this because it means | 2273 // Include the auto-generated part of this file. We split this because it means |
2035 // we can easily edit the non-auto generated parts right here in this file | 2274 // we can easily edit the non-auto generated parts right here in this file |
2036 // instead of having to edit some template or the code generator. | 2275 // instead of having to edit some template or the code generator. |
2037 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 2276 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
2038 | 2277 |
2039 } // namespace gles2 | 2278 } // namespace gles2 |
2040 } // namespace gpu | 2279 } // namespace gpu |
OLD | NEW |