Chromium Code Reviews| 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 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1550 state_.bound_draw_framebuffer.get() == NULL && | 1566 state_.bound_draw_framebuffer.get() == NULL && |
| 1551 surface_->DeferDraws(); | 1567 surface_->DeferDraws(); |
| 1552 } | 1568 } |
| 1553 | 1569 |
| 1554 bool ShouldDeferReads() { | 1570 bool ShouldDeferReads() { |
| 1555 return !offscreen_target_frame_buffer_.get() && | 1571 return !offscreen_target_frame_buffer_.get() && |
| 1556 state_.bound_read_framebuffer.get() == NULL && | 1572 state_.bound_read_framebuffer.get() == NULL && |
| 1557 surface_->DeferDraws(); | 1573 surface_->DeferDraws(); |
| 1558 } | 1574 } |
| 1559 | 1575 |
| 1576 void ProcessPendingReadPixels(); | |
| 1577 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); | |
| 1578 | |
| 1560 void ForceCompileShaderIfPending(Shader* shader); | 1579 void ForceCompileShaderIfPending(Shader* shader); |
| 1561 | 1580 |
| 1562 // Generate a member function prototype for each command in an automated and | 1581 // Generate a member function prototype for each command in an automated and |
| 1563 // typesafe way. | 1582 // typesafe way. |
| 1564 #define GLES2_CMD_OP(name) \ | 1583 #define GLES2_CMD_OP(name) \ |
| 1565 Error Handle ## name( \ | 1584 Error Handle ## name( \ |
| 1566 uint32 immediate_data_size, \ | 1585 uint32 immediate_data_size, \ |
| 1567 const cmds::name& args); \ | 1586 const cmds::name& args); \ |
| 1568 | 1587 |
| 1569 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 1588 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1718 GLsizei viewport_max_width_; | 1737 GLsizei viewport_max_width_; |
| 1719 GLsizei viewport_max_height_; | 1738 GLsizei viewport_max_height_; |
| 1720 | 1739 |
| 1721 // Command buffer stats. | 1740 // Command buffer stats. |
| 1722 int texture_upload_count_; | 1741 int texture_upload_count_; |
| 1723 base::TimeDelta total_texture_upload_time_; | 1742 base::TimeDelta total_texture_upload_time_; |
| 1724 base::TimeDelta total_processing_commands_time_; | 1743 base::TimeDelta total_processing_commands_time_; |
| 1725 | 1744 |
| 1726 scoped_ptr<GPUTracer> gpu_tracer_; | 1745 scoped_ptr<GPUTracer> gpu_tracer_; |
| 1727 | 1746 |
| 1747 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; | |
| 1748 | |
| 1728 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 1749 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
| 1729 }; | 1750 }; |
| 1730 | 1751 |
| 1731 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( | 1752 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( |
| 1732 const char* function_name, GLES2DecoderImpl* decoder) | 1753 const char* function_name, GLES2DecoderImpl* decoder) |
| 1733 : function_name_(function_name), | 1754 : function_name_(function_name), |
| 1734 decoder_(decoder) { | 1755 decoder_(decoder) { |
| 1735 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), | 1756 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), |
| 1736 function_name_); | 1757 function_name_); |
| 1737 } | 1758 } |
| (...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2492 // that can be safely migrated between the iGPU and the dGPU. Mark | 2513 // that can be safely migrated between the iGPU and the dGPU. Mark |
| 2493 // those contexts as safe to forcibly transition between the GPUs. | 2514 // those contexts as safe to forcibly transition between the GPUs. |
| 2494 // http://crbug.com/180876, http://crbug.com/227228 | 2515 // http://crbug.com/180876, http://crbug.com/227228 |
| 2495 if (!offscreen) | 2516 if (!offscreen) |
| 2496 context_->SetSafeToForceGpuSwitch(); | 2517 context_->SetSafeToForceGpuSwitch(); |
| 2497 | 2518 |
| 2498 async_pixel_transfer_manager_.reset( | 2519 async_pixel_transfer_manager_.reset( |
| 2499 AsyncPixelTransferManager::Create(context.get())); | 2520 AsyncPixelTransferManager::Create(context.get())); |
| 2500 async_pixel_transfer_manager_->Initialize(texture_manager()); | 2521 async_pixel_transfer_manager_->Initialize(texture_manager()); |
| 2501 | 2522 |
| 2523 | |
| 2502 return true; | 2524 return true; |
| 2503 } | 2525 } |
| 2504 | 2526 |
| 2505 void GLES2DecoderImpl::UpdateCapabilities() { | 2527 void GLES2DecoderImpl::UpdateCapabilities() { |
| 2506 util_.set_num_compressed_texture_formats( | 2528 util_.set_num_compressed_texture_formats( |
| 2507 validators_->compressed_texture_format.GetValues().size()); | 2529 validators_->compressed_texture_format.GetValues().size()); |
| 2508 util_.set_num_shader_binary_formats( | 2530 util_.set_num_shader_binary_formats( |
| 2509 validators_->shader_binary_format.GetValues().size()); | 2531 validators_->shader_binary_format.GetValues().size()); |
| 2510 } | 2532 } |
| 2511 | 2533 |
| (...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3533 } | 3555 } |
| 3534 GLuint service_id = glCreateShader(type); | 3556 GLuint service_id = glCreateShader(type); |
| 3535 if (service_id != 0) { | 3557 if (service_id != 0) { |
| 3536 CreateShader(client_id, service_id, type); | 3558 CreateShader(client_id, service_id, type); |
| 3537 } | 3559 } |
| 3538 return true; | 3560 return true; |
| 3539 } | 3561 } |
| 3540 | 3562 |
| 3541 void GLES2DecoderImpl::DoFinish() { | 3563 void GLES2DecoderImpl::DoFinish() { |
| 3542 glFinish(); | 3564 glFinish(); |
| 3565 ProcessPendingReadPixels(); | |
| 3543 ProcessPendingQueries(); | 3566 ProcessPendingQueries(); |
| 3544 } | 3567 } |
| 3545 | 3568 |
| 3546 void GLES2DecoderImpl::DoFlush() { | 3569 void GLES2DecoderImpl::DoFlush() { |
| 3547 glFlush(); | 3570 glFlush(); |
| 3548 ProcessPendingQueries(); | 3571 ProcessPendingQueries(); |
| 3549 } | 3572 } |
| 3550 | 3573 |
| 3551 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { | 3574 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { |
| 3552 GLuint texture_index = texture_unit - GL_TEXTURE0; | 3575 GLuint texture_index = texture_unit - GL_TEXTURE0; |
| (...skipping 3148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6701 return error::kNoError; | 6724 return error::kNoError; |
| 6702 } | 6725 } |
| 6703 | 6726 |
| 6704 state_.vertex_attrib_manager->SetDivisor( | 6727 state_.vertex_attrib_manager->SetDivisor( |
| 6705 index, | 6728 index, |
| 6706 divisor); | 6729 divisor); |
| 6707 glVertexAttribDivisorANGLE(index, divisor); | 6730 glVertexAttribDivisorANGLE(index, divisor); |
| 6708 return error::kNoError; | 6731 return error::kNoError; |
| 6709 } | 6732 } |
| 6710 | 6733 |
| 6734 void GLES2DecoderImpl::FinishReadPixels( | |
| 6735 const cmds::ReadPixels& c, | |
| 6736 GLuint buffer) { | |
| 6737 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); | |
| 6738 GLsizei width = c.width; | |
| 6739 GLsizei height = c.height; | |
| 6740 GLenum format = c.format; | |
| 6741 GLenum type = c.type; | |
| 6742 typedef cmds::ReadPixels::Result Result; | |
| 6743 uint32 pixels_size; | |
| 6744 GLES2Util::ComputeImageDataSizes( | |
| 6745 width, height, format, type, state_.pack_alignment, &pixels_size, | |
| 6746 NULL, NULL); | |
| 6747 void* pixels = GetSharedMemoryAs<void*>( | |
| 6748 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); | |
| 6749 if (!pixels) { | |
| 6750 if (buffer != 0) { | |
| 6751 glDeleteBuffersARB(1, &buffer); | |
| 6752 return; | |
| 6753 } | |
| 6754 } | |
| 6755 | |
| 6756 if (buffer != 0) { | |
| 6757 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); | |
| 6758 void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); | |
| 6759 memcpy(pixels, data, pixels_size); | |
| 6760 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't | |
| 6761 // have to restore the state. | |
| 6762 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); | |
| 6763 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | |
| 6764 glDeleteBuffersARB(1, &buffer); | |
| 6765 } | |
| 6766 Result* result = NULL; | |
| 6767 if (c.result_shm_id != 0) { | |
| 6768 result = GetSharedMemoryAs<Result*>( | |
| 6769 c.result_shm_id, c.result_shm_offset, sizeof(*result)); | |
| 6770 if (!result) { | |
| 6771 // No way to mark failure. | |
| 6772 return; | |
| 6773 } | |
| 6774 } | |
|
piman
2013/06/26 22:17:08
It would be good to map the result before the pixe
hubbe
2013/06/28 22:17:49
I'm not sure I understand this, if the client dest
piman
2013/06/28 23:35:46
So, for the synchronous ReadPixels, if the memory
hubbe
2013/06/29 00:13:56
This seems a little silly as async readpixels does
| |
| 6775 | |
| 6776 if (result != NULL) { | |
| 6777 *result = true; | |
| 6778 } | |
| 6779 | |
| 6780 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | |
| 6781 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | |
| 6782 if ((channels_exist & 0x0008) == 0 && | |
| 6783 workarounds().clear_alpha_in_readpixels) { | |
| 6784 // Set the alpha to 255 because some drivers are buggy in this regard. | |
| 6785 uint32 temp_size; | |
| 6786 | |
| 6787 uint32 unpadded_row_size; | |
| 6788 uint32 padded_row_size; | |
| 6789 if (!GLES2Util::ComputeImageDataSizes( | |
| 6790 width, 2, format, type, state_.pack_alignment, &temp_size, | |
| 6791 &unpadded_row_size, &padded_row_size)) { | |
| 6792 return; | |
| 6793 } | |
| 6794 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time | |
| 6795 // of this implementation. | |
| 6796 if (type != GL_UNSIGNED_BYTE) { | |
| 6797 return; | |
| 6798 } | |
| 6799 switch (format) { | |
| 6800 case GL_RGBA: | |
| 6801 case GL_BGRA_EXT: | |
| 6802 case GL_ALPHA: { | |
| 6803 int offset = (format == GL_ALPHA) ? 0 : 3; | |
| 6804 int step = (format == GL_ALPHA) ? 1 : 4; | |
| 6805 uint8* dst = static_cast<uint8*>(pixels) + offset; | |
| 6806 for (GLint yy = 0; yy < height; ++yy) { | |
| 6807 uint8* end = dst + unpadded_row_size; | |
| 6808 for (uint8* d = dst; d < end; d += step) { | |
| 6809 *d = 255; | |
| 6810 } | |
| 6811 dst += padded_row_size; | |
| 6812 } | |
| 6813 break; | |
| 6814 } | |
| 6815 default: | |
| 6816 break; | |
| 6817 } | |
| 6818 } | |
| 6819 } | |
| 6820 | |
| 6821 | |
| 6711 error::Error GLES2DecoderImpl::HandleReadPixels( | 6822 error::Error GLES2DecoderImpl::HandleReadPixels( |
| 6712 uint32 immediate_data_size, const cmds::ReadPixels& c) { | 6823 uint32 immediate_data_size, const cmds::ReadPixels& c) { |
| 6713 if (ShouldDeferReads()) | 6824 if (ShouldDeferReads()) |
| 6714 return error::kDeferCommandUntilLater; | 6825 return error::kDeferCommandUntilLater; |
| 6715 GLint x = c.x; | 6826 GLint x = c.x; |
| 6716 GLint y = c.y; | 6827 GLint y = c.y; |
| 6717 GLsizei width = c.width; | 6828 GLsizei width = c.width; |
| 6718 GLsizei height = c.height; | 6829 GLsizei height = c.height; |
| 6719 GLenum format = c.format; | 6830 GLenum format = c.format; |
| 6720 GLenum type = c.type; | 6831 GLenum type = c.type; |
| 6832 GLboolean async = c.async; | |
| 6721 if (width < 0 || height < 0) { | 6833 if (width < 0 || height < 0) { |
| 6722 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 6834 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
| 6723 return error::kNoError; | 6835 return error::kNoError; |
| 6724 } | 6836 } |
| 6725 typedef cmds::ReadPixels::Result Result; | 6837 typedef cmds::ReadPixels::Result Result; |
| 6726 uint32 pixels_size; | 6838 uint32 pixels_size; |
| 6727 if (!GLES2Util::ComputeImageDataSizes( | 6839 if (!GLES2Util::ComputeImageDataSizes( |
| 6728 width, height, format, type, state_.pack_alignment, &pixels_size, | 6840 width, height, format, type, state_.pack_alignment, &pixels_size, |
| 6729 NULL, NULL)) { | 6841 NULL, NULL)) { |
| 6730 return error::kOutOfBounds; | 6842 return error::kOutOfBounds; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6810 memset(dst, 0, unpadded_row_size); | 6922 memset(dst, 0, unpadded_row_size); |
| 6811 | 6923 |
| 6812 // If the row is in range, copy it. | 6924 // If the row is in range, copy it. |
| 6813 if (ry >= 0 && ry < max_size.height() && read_width > 0) { | 6925 if (ry >= 0 && ry < max_size.height() && read_width > 0) { |
| 6814 glReadPixels( | 6926 glReadPixels( |
| 6815 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); | 6927 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); |
| 6816 } | 6928 } |
| 6817 dst += padded_row_size; | 6929 dst += padded_row_size; |
| 6818 } | 6930 } |
| 6819 } else { | 6931 } else { |
| 6932 if (async && features().use_async_readpixels) { | |
| 6933 GLuint buffer; | |
| 6934 glGenBuffersARB(1, &buffer); | |
| 6935 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); | |
| 6936 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); | |
| 6937 GLenum error = glGetError(); | |
| 6938 if (error == GL_NO_ERROR) { | |
| 6939 glReadPixels(x, y, width, height, format, type, 0); | |
| 6940 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( | |
| 6941 new FenceCallback())); | |
| 6942 WaitForReadPixels(base::Bind( | |
| 6943 &GLES2DecoderImpl::FinishReadPixels, | |
| 6944 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr | |
| 6945 <GLES2DecoderImpl>(this), | |
| 6946 c, buffer)); | |
| 6947 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | |
| 6948 return error::kNoError; | |
| 6949 } | |
| 6950 } | |
| 6820 glReadPixels(x, y, width, height, format, type, pixels); | 6951 glReadPixels(x, y, width, height, format, type, pixels); |
| 6821 } | 6952 } |
| 6822 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); | 6953 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); |
| 6823 if (error == GL_NO_ERROR) { | 6954 if (error == GL_NO_ERROR) { |
| 6824 if (result != NULL) { | 6955 if (result != NULL) { |
| 6825 *result = true; | 6956 *result = true; |
| 6826 } | 6957 } |
| 6827 | 6958 FinishReadPixels(c, 0); |
| 6828 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | |
| 6829 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | |
| 6830 if ((channels_exist & 0x0008) == 0 && | |
| 6831 workarounds().clear_alpha_in_readpixels) { | |
| 6832 // Set the alpha to 255 because some drivers are buggy in this regard. | |
| 6833 uint32 temp_size; | |
| 6834 | |
| 6835 uint32 unpadded_row_size; | |
| 6836 uint32 padded_row_size; | |
| 6837 if (!GLES2Util::ComputeImageDataSizes( | |
| 6838 width, 2, format, type, state_.pack_alignment, &temp_size, | |
| 6839 &unpadded_row_size, &padded_row_size)) { | |
| 6840 LOCAL_SET_GL_ERROR( | |
| 6841 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); | |
| 6842 return error::kNoError; | |
| 6843 } | |
| 6844 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time | |
| 6845 // of this implementation. | |
| 6846 if (type != GL_UNSIGNED_BYTE) { | |
| 6847 LOCAL_SET_GL_ERROR( | |
| 6848 GL_INVALID_OPERATION, "glReadPixels", | |
| 6849 "unsupported readPixel format"); | |
| 6850 return error::kNoError; | |
| 6851 } | |
| 6852 switch (format) { | |
| 6853 case GL_RGBA: | |
| 6854 case GL_BGRA_EXT: | |
| 6855 case GL_ALPHA: { | |
| 6856 int offset = (format == GL_ALPHA) ? 0 : 3; | |
| 6857 int step = (format == GL_ALPHA) ? 1 : 4; | |
| 6858 uint8* dst = static_cast<uint8*>(pixels) + offset; | |
| 6859 for (GLint yy = 0; yy < height; ++yy) { | |
| 6860 uint8* end = dst + unpadded_row_size; | |
| 6861 for (uint8* d = dst; d < end; d += step) { | |
| 6862 *d = 255; | |
| 6863 } | |
| 6864 dst += padded_row_size; | |
| 6865 } | |
| 6866 break; | |
| 6867 } | |
| 6868 default: | |
| 6869 break; | |
| 6870 } | |
| 6871 } | |
| 6872 } | 6959 } |
| 6873 | 6960 |
| 6874 return error::kNoError; | 6961 return error::kNoError; |
| 6875 } | 6962 } |
| 6876 | 6963 |
| 6877 error::Error GLES2DecoderImpl::HandlePixelStorei( | 6964 error::Error GLES2DecoderImpl::HandlePixelStorei( |
| 6878 uint32 immediate_data_size, const cmds::PixelStorei& c) { | 6965 uint32 immediate_data_size, const cmds::PixelStorei& c) { |
| 6879 GLenum pname = c.pname; | 6966 GLenum pname = c.pname; |
| 6880 GLenum param = c.param; | 6967 GLenum param = c.param; |
| 6881 if (!validators_->pixel_store.IsValid(pname)) { | 6968 if (!validators_->pixel_store.IsValid(pname)) { |
| (...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9091 bool GLES2DecoderImpl::ProcessPendingQueries() { | 9178 bool GLES2DecoderImpl::ProcessPendingQueries() { |
| 9092 if (query_manager_.get() == NULL) { | 9179 if (query_manager_.get() == NULL) { |
| 9093 return false; | 9180 return false; |
| 9094 } | 9181 } |
| 9095 if (!query_manager_->ProcessPendingQueries()) { | 9182 if (!query_manager_->ProcessPendingQueries()) { |
| 9096 current_decoder_error_ = error::kOutOfBounds; | 9183 current_decoder_error_ = error::kOutOfBounds; |
| 9097 } | 9184 } |
| 9098 return query_manager_->HavePendingQueries(); | 9185 return query_manager_->HavePendingQueries(); |
| 9099 } | 9186 } |
| 9100 | 9187 |
| 9188 // Note that if there are no pending readpixels right now, | |
| 9189 // this function will call the callback immediately. | |
| 9190 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) { | |
| 9191 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) { | |
| 9192 pending_readpixel_fences_.back()->callbacks.push_back(callback); | |
| 9193 } else { | |
| 9194 callback.Run(); | |
| 9195 } | |
| 9196 } | |
| 9197 | |
| 9198 void GLES2DecoderImpl::ProcessPendingReadPixels() { | |
| 9199 while (!pending_readpixel_fences_.empty() && | |
| 9200 pending_readpixel_fences_.front()->fence->HasCompleted()) { | |
| 9201 std::vector<base::Closure> callbacks = | |
| 9202 pending_readpixel_fences_.front()->callbacks; | |
| 9203 pending_readpixel_fences_.pop(); | |
| 9204 for (size_t i = 0; i < callbacks.size(); i++) { | |
| 9205 callbacks[i].Run(); | |
| 9206 } | |
| 9207 } | |
| 9208 } | |
| 9209 | |
| 9101 bool GLES2DecoderImpl::HasMoreIdleWork() { | 9210 bool GLES2DecoderImpl::HasMoreIdleWork() { |
| 9102 return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); | 9211 return !pending_readpixel_fences_.empty() || |
| 9212 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); | |
| 9103 } | 9213 } |
| 9104 | 9214 |
| 9105 void GLES2DecoderImpl::PerformIdleWork() { | 9215 void GLES2DecoderImpl::PerformIdleWork() { |
| 9216 ProcessPendingReadPixels(); | |
| 9106 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) | 9217 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) |
| 9107 return; | 9218 return; |
| 9108 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); | 9219 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); |
| 9109 ProcessFinishedAsyncTransfers(); | 9220 ProcessFinishedAsyncTransfers(); |
| 9110 } | 9221 } |
| 9111 | 9222 |
| 9112 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( | 9223 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( |
| 9113 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { | 9224 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { |
| 9114 GLenum target = static_cast<GLenum>(c.target); | 9225 GLenum target = static_cast<GLenum>(c.target); |
| 9115 GLuint client_id = static_cast<GLuint>(c.id); | 9226 GLuint client_id = static_cast<GLuint>(c.id); |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10346 return error::kNoError; | 10457 return error::kNoError; |
| 10347 } | 10458 } |
| 10348 | 10459 |
| 10349 // Include the auto-generated part of this file. We split this because it means | 10460 // Include the auto-generated part of this file. We split this because it means |
| 10350 // we can easily edit the non-auto generated parts right here in this file | 10461 // we can easily edit the non-auto generated parts right here in this file |
| 10351 // instead of having to edit some template or the code generator. | 10462 // instead of having to edit some template or the code generator. |
| 10352 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10463 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 10353 | 10464 |
| 10354 } // namespace gles2 | 10465 } // namespace gles2 |
| 10355 } // namespace gpu | 10466 } // namespace gpu |
| OLD | NEW |