OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 52 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
53 #include "gpu/command_buffer/service/shader_manager.h" | 53 #include "gpu/command_buffer/service/shader_manager.h" |
54 #include "gpu/command_buffer/service/shader_translator.h" | 54 #include "gpu/command_buffer/service/shader_translator.h" |
55 #include "gpu/command_buffer/service/shader_translator_cache.h" | 55 #include "gpu/command_buffer/service/shader_translator_cache.h" |
56 #include "gpu/command_buffer/service/stream_texture.h" | 56 #include "gpu/command_buffer/service/stream_texture.h" |
57 #include "gpu/command_buffer/service/stream_texture_manager.h" | 57 #include "gpu/command_buffer/service/stream_texture_manager.h" |
58 #include "gpu/command_buffer/service/texture_manager.h" | 58 #include "gpu/command_buffer/service/texture_manager.h" |
59 #include "gpu/command_buffer/service/vertex_array_manager.h" | 59 #include "gpu/command_buffer/service/vertex_array_manager.h" |
60 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 60 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
61 #include "ui/gl/gl_bindings.h" | 61 #include "ui/gl/gl_bindings.h" |
| 62 #include "ui/gl/gl_fence.h" |
62 #include "ui/gl/gl_image.h" | 63 #include "ui/gl/gl_image.h" |
63 #include "ui/gl/gl_implementation.h" | 64 #include "ui/gl/gl_implementation.h" |
64 #include "ui/gl/gl_surface.h" | 65 #include "ui/gl/gl_surface.h" |
65 | 66 |
66 #if defined(OS_MACOSX) | 67 #if defined(OS_MACOSX) |
67 #include "ui/gl/io_surface_support_mac.h" | 68 #include "ui/gl/io_surface_support_mac.h" |
68 #endif | 69 #endif |
69 | 70 |
70 // TODO(zmo): we can't include "City.h" due to type def conflicts. | 71 // TODO(zmo): we can't include "City.h" due to type def conflicts. |
71 extern uint64 CityHash64(const char*, size_t); | 72 extern uint64 CityHash64(const char*, size_t); |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 GLuint id() const { | 471 GLuint id() const { |
471 return id_; | 472 return id_; |
472 } | 473 } |
473 | 474 |
474 private: | 475 private: |
475 GLES2DecoderImpl* decoder_; | 476 GLES2DecoderImpl* decoder_; |
476 GLuint id_; | 477 GLuint id_; |
477 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); | 478 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); |
478 }; | 479 }; |
479 | 480 |
| 481 struct FenceCallback { |
| 482 explicit FenceCallback() |
| 483 : fence(gfx::GLFence::Create()) { |
| 484 DCHECK(fence); |
| 485 } |
| 486 void AddCallback(base::Closure cb) { |
| 487 callbacks.push_back(cb); |
| 488 } |
| 489 std::vector<base::Closure> callbacks; |
| 490 scoped_ptr<gfx::GLFence> fence; |
| 491 }; |
| 492 |
| 493 |
480 // } // anonymous namespace. | 494 // } // anonymous namespace. |
481 | 495 |
482 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, | 496 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, |
483 uint32* service_texture_id) { | 497 uint32* service_texture_id) { |
484 return false; | 498 return false; |
485 } | 499 } |
486 | 500 |
487 GLES2Decoder::GLES2Decoder() | 501 GLES2Decoder::GLES2Decoder() |
488 : initialized_(false), | 502 : initialized_(false), |
489 debug_(false), | 503 debug_(false), |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 virtual QueryManager* GetQueryManager() OVERRIDE { | 594 virtual QueryManager* GetQueryManager() OVERRIDE { |
581 return query_manager_.get(); | 595 return query_manager_.get(); |
582 } | 596 } |
583 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { | 597 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { |
584 return vertex_array_manager_.get(); | 598 return vertex_array_manager_.get(); |
585 } | 599 } |
586 virtual bool ProcessPendingQueries() OVERRIDE; | 600 virtual bool ProcessPendingQueries() OVERRIDE; |
587 virtual bool HasMoreIdleWork() OVERRIDE; | 601 virtual bool HasMoreIdleWork() OVERRIDE; |
588 virtual void PerformIdleWork() OVERRIDE; | 602 virtual void PerformIdleWork() OVERRIDE; |
589 | 603 |
| 604 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE; |
| 605 |
590 virtual void SetResizeCallback( | 606 virtual void SetResizeCallback( |
591 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; | 607 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; |
592 | 608 |
593 virtual Logger* GetLogger() OVERRIDE; | 609 virtual Logger* GetLogger() OVERRIDE; |
594 virtual ErrorState* GetErrorState() OVERRIDE; | 610 virtual ErrorState* GetErrorState() OVERRIDE; |
595 | 611 |
596 virtual void SetShaderCacheCallback( | 612 virtual void SetShaderCacheCallback( |
597 const ShaderCacheCallback& callback) OVERRIDE; | 613 const ShaderCacheCallback& callback) OVERRIDE; |
598 virtual void SetWaitSyncPointCallback( | 614 virtual void SetWaitSyncPointCallback( |
599 const WaitSyncPointCallback& callback) OVERRIDE; | 615 const WaitSyncPointCallback& callback) OVERRIDE; |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 state_.bound_draw_framebuffer.get() == NULL && | 1570 state_.bound_draw_framebuffer.get() == NULL && |
1555 surface_->DeferDraws(); | 1571 surface_->DeferDraws(); |
1556 } | 1572 } |
1557 | 1573 |
1558 bool ShouldDeferReads() { | 1574 bool ShouldDeferReads() { |
1559 return !offscreen_target_frame_buffer_.get() && | 1575 return !offscreen_target_frame_buffer_.get() && |
1560 state_.bound_read_framebuffer.get() == NULL && | 1576 state_.bound_read_framebuffer.get() == NULL && |
1561 surface_->DeferDraws(); | 1577 surface_->DeferDraws(); |
1562 } | 1578 } |
1563 | 1579 |
| 1580 void ProcessPendingReadPixels(); |
| 1581 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); |
| 1582 |
1564 void ForceCompileShaderIfPending(Shader* shader); | 1583 void ForceCompileShaderIfPending(Shader* shader); |
1565 | 1584 |
1566 // Generate a member function prototype for each command in an automated and | 1585 // Generate a member function prototype for each command in an automated and |
1567 // typesafe way. | 1586 // typesafe way. |
1568 #define GLES2_CMD_OP(name) \ | 1587 #define GLES2_CMD_OP(name) \ |
1569 Error Handle ## name( \ | 1588 Error Handle ## name( \ |
1570 uint32 immediate_data_size, \ | 1589 uint32 immediate_data_size, \ |
1571 const cmds::name& args); \ | 1590 const cmds::name& args); \ |
1572 | 1591 |
1573 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 1592 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 GLsizei viewport_max_width_; | 1741 GLsizei viewport_max_width_; |
1723 GLsizei viewport_max_height_; | 1742 GLsizei viewport_max_height_; |
1724 | 1743 |
1725 // Command buffer stats. | 1744 // Command buffer stats. |
1726 int texture_upload_count_; | 1745 int texture_upload_count_; |
1727 base::TimeDelta total_texture_upload_time_; | 1746 base::TimeDelta total_texture_upload_time_; |
1728 base::TimeDelta total_processing_commands_time_; | 1747 base::TimeDelta total_processing_commands_time_; |
1729 | 1748 |
1730 scoped_ptr<GPUTracer> gpu_tracer_; | 1749 scoped_ptr<GPUTracer> gpu_tracer_; |
1731 | 1750 |
| 1751 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; |
| 1752 |
1732 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 1753 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
1733 }; | 1754 }; |
1734 | 1755 |
1735 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( | 1756 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( |
1736 const char* function_name, GLES2DecoderImpl* decoder) | 1757 const char* function_name, GLES2DecoderImpl* decoder) |
1737 : function_name_(function_name), | 1758 : function_name_(function_name), |
1738 decoder_(decoder) { | 1759 decoder_(decoder) { |
1739 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), | 1760 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), |
1740 function_name_); | 1761 function_name_); |
1741 } | 1762 } |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2813 // Rebind the FBO if it was unbound by the context. | 2834 // Rebind the FBO if it was unbound by the context. |
2814 if (workarounds().unbind_fbo_on_context_switch) | 2835 if (workarounds().unbind_fbo_on_context_switch) |
2815 RestoreFramebufferBindings(); | 2836 RestoreFramebufferBindings(); |
2816 | 2837 |
2817 clear_state_dirty_ = true; | 2838 clear_state_dirty_ = true; |
2818 | 2839 |
2819 return true; | 2840 return true; |
2820 } | 2841 } |
2821 | 2842 |
2822 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { | 2843 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { |
| 2844 ProcessPendingReadPixels(); |
2823 if (engine() && query_manager_.get()) | 2845 if (engine() && query_manager_.get()) |
2824 query_manager_->ProcessPendingTransferQueries(); | 2846 query_manager_->ProcessPendingTransferQueries(); |
2825 | 2847 |
2826 // TODO(epenner): Is there a better place to do this? | 2848 // TODO(epenner): Is there a better place to do this? |
2827 // This needs to occur before we execute any batch of commands | 2849 // This needs to occur before we execute any batch of commands |
2828 // from the client, as the client may have recieved an async | 2850 // from the client, as the client may have recieved an async |
2829 // completion while issuing those commands. | 2851 // completion while issuing those commands. |
2830 // "DidFlushStart" would be ideal if we had such a callback. | 2852 // "DidFlushStart" would be ideal if we had such a callback. |
2831 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); | 2853 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); |
2832 } | 2854 } |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3541 } | 3563 } |
3542 GLuint service_id = glCreateShader(type); | 3564 GLuint service_id = glCreateShader(type); |
3543 if (service_id != 0) { | 3565 if (service_id != 0) { |
3544 CreateShader(client_id, service_id, type); | 3566 CreateShader(client_id, service_id, type); |
3545 } | 3567 } |
3546 return true; | 3568 return true; |
3547 } | 3569 } |
3548 | 3570 |
3549 void GLES2DecoderImpl::DoFinish() { | 3571 void GLES2DecoderImpl::DoFinish() { |
3550 glFinish(); | 3572 glFinish(); |
| 3573 ProcessPendingReadPixels(); |
3551 ProcessPendingQueries(); | 3574 ProcessPendingQueries(); |
3552 } | 3575 } |
3553 | 3576 |
3554 void GLES2DecoderImpl::DoFlush() { | 3577 void GLES2DecoderImpl::DoFlush() { |
3555 glFlush(); | 3578 glFlush(); |
3556 ProcessPendingQueries(); | 3579 ProcessPendingQueries(); |
3557 } | 3580 } |
3558 | 3581 |
3559 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { | 3582 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { |
3560 GLuint texture_index = texture_unit - GL_TEXTURE0; | 3583 GLuint texture_index = texture_unit - GL_TEXTURE0; |
(...skipping 3194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6755 return error::kNoError; | 6778 return error::kNoError; |
6756 } | 6779 } |
6757 | 6780 |
6758 state_.vertex_attrib_manager->SetDivisor( | 6781 state_.vertex_attrib_manager->SetDivisor( |
6759 index, | 6782 index, |
6760 divisor); | 6783 divisor); |
6761 glVertexAttribDivisorANGLE(index, divisor); | 6784 glVertexAttribDivisorANGLE(index, divisor); |
6762 return error::kNoError; | 6785 return error::kNoError; |
6763 } | 6786 } |
6764 | 6787 |
| 6788 void GLES2DecoderImpl::FinishReadPixels( |
| 6789 const cmds::ReadPixels& c, |
| 6790 GLuint buffer) { |
| 6791 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); |
| 6792 GLsizei width = c.width; |
| 6793 GLsizei height = c.height; |
| 6794 GLenum format = c.format; |
| 6795 GLenum type = c.type; |
| 6796 typedef cmds::ReadPixels::Result Result; |
| 6797 uint32 pixels_size; |
| 6798 Result* result = NULL; |
| 6799 if (c.result_shm_id != 0) { |
| 6800 result = GetSharedMemoryAs<Result*>( |
| 6801 c.result_shm_id, c.result_shm_offset, sizeof(*result)); |
| 6802 if (!result) { |
| 6803 if (buffer != 0) { |
| 6804 glDeleteBuffersARB(1, &buffer); |
| 6805 } |
| 6806 return; |
| 6807 } |
| 6808 } |
| 6809 GLES2Util::ComputeImageDataSizes( |
| 6810 width, height, format, type, state_.pack_alignment, &pixels_size, |
| 6811 NULL, NULL); |
| 6812 void* pixels = GetSharedMemoryAs<void*>( |
| 6813 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); |
| 6814 if (!pixels) { |
| 6815 if (buffer != 0) { |
| 6816 glDeleteBuffersARB(1, &buffer); |
| 6817 } |
| 6818 return; |
| 6819 } |
| 6820 |
| 6821 if (buffer != 0) { |
| 6822 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); |
| 6823 void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); |
| 6824 memcpy(pixels, data, pixels_size); |
| 6825 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't |
| 6826 // have to restore the state. |
| 6827 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); |
| 6828 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
| 6829 glDeleteBuffersARB(1, &buffer); |
| 6830 } |
| 6831 |
| 6832 if (result != NULL) { |
| 6833 *result = true; |
| 6834 } |
| 6835 |
| 6836 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 6837 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 6838 if ((channels_exist & 0x0008) == 0 && |
| 6839 workarounds().clear_alpha_in_readpixels) { |
| 6840 // Set the alpha to 255 because some drivers are buggy in this regard. |
| 6841 uint32 temp_size; |
| 6842 |
| 6843 uint32 unpadded_row_size; |
| 6844 uint32 padded_row_size; |
| 6845 if (!GLES2Util::ComputeImageDataSizes( |
| 6846 width, 2, format, type, state_.pack_alignment, &temp_size, |
| 6847 &unpadded_row_size, &padded_row_size)) { |
| 6848 return; |
| 6849 } |
| 6850 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time |
| 6851 // of this implementation. |
| 6852 if (type != GL_UNSIGNED_BYTE) { |
| 6853 return; |
| 6854 } |
| 6855 switch (format) { |
| 6856 case GL_RGBA: |
| 6857 case GL_BGRA_EXT: |
| 6858 case GL_ALPHA: { |
| 6859 int offset = (format == GL_ALPHA) ? 0 : 3; |
| 6860 int step = (format == GL_ALPHA) ? 1 : 4; |
| 6861 uint8* dst = static_cast<uint8*>(pixels) + offset; |
| 6862 for (GLint yy = 0; yy < height; ++yy) { |
| 6863 uint8* end = dst + unpadded_row_size; |
| 6864 for (uint8* d = dst; d < end; d += step) { |
| 6865 *d = 255; |
| 6866 } |
| 6867 dst += padded_row_size; |
| 6868 } |
| 6869 break; |
| 6870 } |
| 6871 default: |
| 6872 break; |
| 6873 } |
| 6874 } |
| 6875 } |
| 6876 |
| 6877 |
6765 error::Error GLES2DecoderImpl::HandleReadPixels( | 6878 error::Error GLES2DecoderImpl::HandleReadPixels( |
6766 uint32 immediate_data_size, const cmds::ReadPixels& c) { | 6879 uint32 immediate_data_size, const cmds::ReadPixels& c) { |
6767 if (ShouldDeferReads()) | 6880 if (ShouldDeferReads()) |
6768 return error::kDeferCommandUntilLater; | 6881 return error::kDeferCommandUntilLater; |
6769 GLint x = c.x; | 6882 GLint x = c.x; |
6770 GLint y = c.y; | 6883 GLint y = c.y; |
6771 GLsizei width = c.width; | 6884 GLsizei width = c.width; |
6772 GLsizei height = c.height; | 6885 GLsizei height = c.height; |
6773 GLenum format = c.format; | 6886 GLenum format = c.format; |
6774 GLenum type = c.type; | 6887 GLenum type = c.type; |
| 6888 GLboolean async = c.async; |
6775 if (width < 0 || height < 0) { | 6889 if (width < 0 || height < 0) { |
6776 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 6890 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
6777 return error::kNoError; | 6891 return error::kNoError; |
6778 } | 6892 } |
6779 typedef cmds::ReadPixels::Result Result; | 6893 typedef cmds::ReadPixels::Result Result; |
6780 uint32 pixels_size; | 6894 uint32 pixels_size; |
6781 if (!GLES2Util::ComputeImageDataSizes( | 6895 if (!GLES2Util::ComputeImageDataSizes( |
6782 width, height, format, type, state_.pack_alignment, &pixels_size, | 6896 width, height, format, type, state_.pack_alignment, &pixels_size, |
6783 NULL, NULL)) { | 6897 NULL, NULL)) { |
6784 return error::kOutOfBounds; | 6898 return error::kOutOfBounds; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6864 memset(dst, 0, unpadded_row_size); | 6978 memset(dst, 0, unpadded_row_size); |
6865 | 6979 |
6866 // If the row is in range, copy it. | 6980 // If the row is in range, copy it. |
6867 if (ry >= 0 && ry < max_size.height() && read_width > 0) { | 6981 if (ry >= 0 && ry < max_size.height() && read_width > 0) { |
6868 glReadPixels( | 6982 glReadPixels( |
6869 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); | 6983 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); |
6870 } | 6984 } |
6871 dst += padded_row_size; | 6985 dst += padded_row_size; |
6872 } | 6986 } |
6873 } else { | 6987 } else { |
| 6988 if (async && features().use_async_readpixels) { |
| 6989 GLuint buffer; |
| 6990 glGenBuffersARB(1, &buffer); |
| 6991 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); |
| 6992 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); |
| 6993 GLenum error = glGetError(); |
| 6994 if (error == GL_NO_ERROR) { |
| 6995 glReadPixels(x, y, width, height, format, type, 0); |
| 6996 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( |
| 6997 new FenceCallback())); |
| 6998 WaitForReadPixels(base::Bind( |
| 6999 &GLES2DecoderImpl::FinishReadPixels, |
| 7000 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr |
| 7001 <GLES2DecoderImpl>(this), |
| 7002 c, buffer)); |
| 7003 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
| 7004 return error::kNoError; |
| 7005 } |
| 7006 } |
6874 glReadPixels(x, y, width, height, format, type, pixels); | 7007 glReadPixels(x, y, width, height, format, type, pixels); |
6875 } | 7008 } |
6876 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); | 7009 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); |
6877 if (error == GL_NO_ERROR) { | 7010 if (error == GL_NO_ERROR) { |
6878 if (result != NULL) { | 7011 if (result != NULL) { |
6879 *result = true; | 7012 *result = true; |
6880 } | 7013 } |
6881 | 7014 FinishReadPixels(c, 0); |
6882 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | |
6883 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | |
6884 if ((channels_exist & 0x0008) == 0 && | |
6885 workarounds().clear_alpha_in_readpixels) { | |
6886 // Set the alpha to 255 because some drivers are buggy in this regard. | |
6887 uint32 temp_size; | |
6888 | |
6889 uint32 unpadded_row_size; | |
6890 uint32 padded_row_size; | |
6891 if (!GLES2Util::ComputeImageDataSizes( | |
6892 width, 2, format, type, state_.pack_alignment, &temp_size, | |
6893 &unpadded_row_size, &padded_row_size)) { | |
6894 LOCAL_SET_GL_ERROR( | |
6895 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); | |
6896 return error::kNoError; | |
6897 } | |
6898 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time | |
6899 // of this implementation. | |
6900 if (type != GL_UNSIGNED_BYTE) { | |
6901 LOCAL_SET_GL_ERROR( | |
6902 GL_INVALID_OPERATION, "glReadPixels", | |
6903 "unsupported readPixel format"); | |
6904 return error::kNoError; | |
6905 } | |
6906 switch (format) { | |
6907 case GL_RGBA: | |
6908 case GL_BGRA_EXT: | |
6909 case GL_ALPHA: { | |
6910 int offset = (format == GL_ALPHA) ? 0 : 3; | |
6911 int step = (format == GL_ALPHA) ? 1 : 4; | |
6912 uint8* dst = static_cast<uint8*>(pixels) + offset; | |
6913 for (GLint yy = 0; yy < height; ++yy) { | |
6914 uint8* end = dst + unpadded_row_size; | |
6915 for (uint8* d = dst; d < end; d += step) { | |
6916 *d = 255; | |
6917 } | |
6918 dst += padded_row_size; | |
6919 } | |
6920 break; | |
6921 } | |
6922 default: | |
6923 break; | |
6924 } | |
6925 } | |
6926 } | 7015 } |
6927 | 7016 |
6928 return error::kNoError; | 7017 return error::kNoError; |
6929 } | 7018 } |
6930 | 7019 |
6931 error::Error GLES2DecoderImpl::HandlePixelStorei( | 7020 error::Error GLES2DecoderImpl::HandlePixelStorei( |
6932 uint32 immediate_data_size, const cmds::PixelStorei& c) { | 7021 uint32 immediate_data_size, const cmds::PixelStorei& c) { |
6933 GLenum pname = c.pname; | 7022 GLenum pname = c.pname; |
6934 GLenum param = c.param; | 7023 GLenum param = c.param; |
6935 if (!validators_->pixel_store.IsValid(pname)) { | 7024 if (!validators_->pixel_store.IsValid(pname)) { |
(...skipping 2181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9117 bool GLES2DecoderImpl::ProcessPendingQueries() { | 9206 bool GLES2DecoderImpl::ProcessPendingQueries() { |
9118 if (query_manager_.get() == NULL) { | 9207 if (query_manager_.get() == NULL) { |
9119 return false; | 9208 return false; |
9120 } | 9209 } |
9121 if (!query_manager_->ProcessPendingQueries()) { | 9210 if (!query_manager_->ProcessPendingQueries()) { |
9122 current_decoder_error_ = error::kOutOfBounds; | 9211 current_decoder_error_ = error::kOutOfBounds; |
9123 } | 9212 } |
9124 return query_manager_->HavePendingQueries(); | 9213 return query_manager_->HavePendingQueries(); |
9125 } | 9214 } |
9126 | 9215 |
| 9216 // Note that if there are no pending readpixels right now, |
| 9217 // this function will call the callback immediately. |
| 9218 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) { |
| 9219 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) { |
| 9220 pending_readpixel_fences_.back()->callbacks.push_back(callback); |
| 9221 } else { |
| 9222 callback.Run(); |
| 9223 } |
| 9224 } |
| 9225 |
| 9226 void GLES2DecoderImpl::ProcessPendingReadPixels() { |
| 9227 while (!pending_readpixel_fences_.empty() && |
| 9228 pending_readpixel_fences_.front()->fence->HasCompleted()) { |
| 9229 std::vector<base::Closure> callbacks = |
| 9230 pending_readpixel_fences_.front()->callbacks; |
| 9231 pending_readpixel_fences_.pop(); |
| 9232 for (size_t i = 0; i < callbacks.size(); i++) { |
| 9233 callbacks[i].Run(); |
| 9234 } |
| 9235 } |
| 9236 } |
| 9237 |
9127 bool GLES2DecoderImpl::HasMoreIdleWork() { | 9238 bool GLES2DecoderImpl::HasMoreIdleWork() { |
9128 return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); | 9239 return !pending_readpixel_fences_.empty() || |
| 9240 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); |
9129 } | 9241 } |
9130 | 9242 |
9131 void GLES2DecoderImpl::PerformIdleWork() { | 9243 void GLES2DecoderImpl::PerformIdleWork() { |
| 9244 ProcessPendingReadPixels(); |
9132 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) | 9245 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) |
9133 return; | 9246 return; |
9134 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); | 9247 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); |
9135 ProcessFinishedAsyncTransfers(); | 9248 ProcessFinishedAsyncTransfers(); |
9136 } | 9249 } |
9137 | 9250 |
9138 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( | 9251 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( |
9139 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { | 9252 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { |
9140 GLenum target = static_cast<GLenum>(c.target); | 9253 GLenum target = static_cast<GLenum>(c.target); |
9141 GLuint client_id = static_cast<GLuint>(c.id); | 9254 GLuint client_id = static_cast<GLuint>(c.id); |
9142 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); | 9255 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); |
9143 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); | 9256 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); |
9144 | 9257 |
9145 switch (target) { | 9258 switch (target) { |
9146 case GL_COMMANDS_ISSUED_CHROMIUM: | 9259 case GL_COMMANDS_ISSUED_CHROMIUM: |
9147 case GL_LATENCY_QUERY_CHROMIUM: | 9260 case GL_LATENCY_QUERY_CHROMIUM: |
9148 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: | 9261 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: |
| 9262 case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: |
9149 case GL_GET_ERROR_QUERY_CHROMIUM: | 9263 case GL_GET_ERROR_QUERY_CHROMIUM: |
9150 break; | 9264 break; |
9151 default: | 9265 default: |
9152 if (!features().occlusion_query_boolean) { | 9266 if (!features().occlusion_query_boolean) { |
9153 LOCAL_SET_GL_ERROR( | 9267 LOCAL_SET_GL_ERROR( |
9154 GL_INVALID_OPERATION, "glBeginQueryEXT", | 9268 GL_INVALID_OPERATION, "glBeginQueryEXT", |
9155 "not enabled for occlusion queries"); | 9269 "not enabled for occlusion queries"); |
9156 return error::kNoError; | 9270 return error::kNoError; |
9157 } | 9271 } |
9158 break; | 9272 break; |
9159 } | 9273 } |
9160 | 9274 |
| 9275 // TODO(hubbe): Make it possible to have one query per type running at the |
| 9276 // same time. |
9161 if (state_.current_query.get()) { | 9277 if (state_.current_query.get()) { |
9162 LOCAL_SET_GL_ERROR( | 9278 LOCAL_SET_GL_ERROR( |
9163 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); | 9279 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); |
9164 return error::kNoError; | 9280 return error::kNoError; |
9165 } | 9281 } |
9166 | 9282 |
9167 if (client_id == 0) { | 9283 if (client_id == 0) { |
9168 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); | 9284 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); |
9169 return error::kNoError; | 9285 return error::kNoError; |
9170 } | 9286 } |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10372 return error::kNoError; | 10488 return error::kNoError; |
10373 } | 10489 } |
10374 | 10490 |
10375 // Include the auto-generated part of this file. We split this because it means | 10491 // Include the auto-generated part of this file. We split this because it means |
10376 // we can easily edit the non-auto generated parts right here in this file | 10492 // we can easily edit the non-auto generated parts right here in this file |
10377 // instead of having to edit some template or the code generator. | 10493 // instead of having to edit some template or the code generator. |
10378 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10494 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
10379 | 10495 |
10380 } // namespace gles2 | 10496 } // namespace gles2 |
10381 } // namespace gpu | 10497 } // namespace gpu |
OLD | NEW |