Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 16831004: Perform glReadPixels with PBOs in the gpu, if PBOs are available. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: revert gl_in_process_context.cc, deal with out-of-order callbacks in gl_helper.cc Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
piman 2013/07/01 22:24:08 nit: extra blank line unnecessary.
hubbe 2013/07/01 22:34:41 Done.
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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 // Rebind the FBO if it was unbound by the context. 2823 // Rebind the FBO if it was unbound by the context.
2802 if (workarounds().unbind_fbo_on_context_switch) 2824 if (workarounds().unbind_fbo_on_context_switch)
2803 RestoreFramebufferBindings(); 2825 RestoreFramebufferBindings();
2804 2826
2805 clear_state_dirty_ = true; 2827 clear_state_dirty_ = true;
2806 2828
2807 return true; 2829 return true;
2808 } 2830 }
2809 2831
2810 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { 2832 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
2833 ProcessPendingReadPixels();
2811 if (engine() && query_manager_.get()) 2834 if (engine() && query_manager_.get())
2812 query_manager_->ProcessPendingTransferQueries(); 2835 query_manager_->ProcessPendingTransferQueries();
2813 2836
2814 // TODO(epenner): Is there a better place to do this? 2837 // TODO(epenner): Is there a better place to do this?
2815 // This needs to occur before we execute any batch of commands 2838 // This needs to occur before we execute any batch of commands
2816 // from the client, as the client may have recieved an async 2839 // from the client, as the client may have recieved an async
2817 // completion while issuing those commands. 2840 // completion while issuing those commands.
2818 // "DidFlushStart" would be ideal if we had such a callback. 2841 // "DidFlushStart" would be ideal if we had such a callback.
2819 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); 2842 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
2820 } 2843 }
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
3533 } 3556 }
3534 GLuint service_id = glCreateShader(type); 3557 GLuint service_id = glCreateShader(type);
3535 if (service_id != 0) { 3558 if (service_id != 0) {
3536 CreateShader(client_id, service_id, type); 3559 CreateShader(client_id, service_id, type);
3537 } 3560 }
3538 return true; 3561 return true;
3539 } 3562 }
3540 3563
3541 void GLES2DecoderImpl::DoFinish() { 3564 void GLES2DecoderImpl::DoFinish() {
3542 glFinish(); 3565 glFinish();
3566 ProcessPendingReadPixels();
3543 ProcessPendingQueries(); 3567 ProcessPendingQueries();
3544 } 3568 }
3545 3569
3546 void GLES2DecoderImpl::DoFlush() { 3570 void GLES2DecoderImpl::DoFlush() {
3547 glFlush(); 3571 glFlush();
3548 ProcessPendingQueries(); 3572 ProcessPendingQueries();
3549 } 3573 }
3550 3574
3551 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { 3575 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
3552 GLuint texture_index = texture_unit - GL_TEXTURE0; 3576 GLuint texture_index = texture_unit - GL_TEXTURE0;
(...skipping 3148 matching lines...) Expand 10 before | Expand all | Expand 10 after
6701 return error::kNoError; 6725 return error::kNoError;
6702 } 6726 }
6703 6727
6704 state_.vertex_attrib_manager->SetDivisor( 6728 state_.vertex_attrib_manager->SetDivisor(
6705 index, 6729 index,
6706 divisor); 6730 divisor);
6707 glVertexAttribDivisorANGLE(index, divisor); 6731 glVertexAttribDivisorANGLE(index, divisor);
6708 return error::kNoError; 6732 return error::kNoError;
6709 } 6733 }
6710 6734
6735 void GLES2DecoderImpl::FinishReadPixels(
6736 const cmds::ReadPixels& c,
6737 GLuint buffer) {
6738 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
6739 GLsizei width = c.width;
6740 GLsizei height = c.height;
6741 GLenum format = c.format;
6742 GLenum type = c.type;
6743 typedef cmds::ReadPixels::Result Result;
6744 uint32 pixels_size;
6745 Result* result = NULL;
6746 if (c.result_shm_id != 0) {
6747 result = GetSharedMemoryAs<Result*>(
6748 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6749 if (!result) {
6750 if (buffer != 0) {
6751 glDeleteBuffersARB(1, &buffer);
6752 }
6753 return;
6754 }
6755 }
6756 GLES2Util::ComputeImageDataSizes(
6757 width, height, format, type, state_.pack_alignment, &pixels_size,
6758 NULL, NULL);
6759 void* pixels = GetSharedMemoryAs<void*>(
6760 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
6761 if (!pixels) {
6762 if (buffer != 0) {
6763 glDeleteBuffersARB(1, &buffer);
6764 }
6765 return;
6766 }
6767
6768 if (buffer != 0) {
6769 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
6770 void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
6771 memcpy(pixels, data, pixels_size);
6772 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
6773 // have to restore the state.
6774 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
6775 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
6776 glDeleteBuffersARB(1, &buffer);
6777 }
6778
6779 if (result != NULL) {
6780 *result = true;
6781 }
6782
6783 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6784 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
6785 if ((channels_exist & 0x0008) == 0 &&
6786 workarounds().clear_alpha_in_readpixels) {
6787 // Set the alpha to 255 because some drivers are buggy in this regard.
6788 uint32 temp_size;
6789
6790 uint32 unpadded_row_size;
6791 uint32 padded_row_size;
6792 if (!GLES2Util::ComputeImageDataSizes(
6793 width, 2, format, type, state_.pack_alignment, &temp_size,
6794 &unpadded_row_size, &padded_row_size)) {
6795 return;
6796 }
6797 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6798 // of this implementation.
6799 if (type != GL_UNSIGNED_BYTE) {
6800 return;
6801 }
6802 switch (format) {
6803 case GL_RGBA:
6804 case GL_BGRA_EXT:
6805 case GL_ALPHA: {
6806 int offset = (format == GL_ALPHA) ? 0 : 3;
6807 int step = (format == GL_ALPHA) ? 1 : 4;
6808 uint8* dst = static_cast<uint8*>(pixels) + offset;
6809 for (GLint yy = 0; yy < height; ++yy) {
6810 uint8* end = dst + unpadded_row_size;
6811 for (uint8* d = dst; d < end; d += step) {
6812 *d = 255;
6813 }
6814 dst += padded_row_size;
6815 }
6816 break;
6817 }
6818 default:
6819 break;
6820 }
6821 }
6822 }
6823
6824
6711 error::Error GLES2DecoderImpl::HandleReadPixels( 6825 error::Error GLES2DecoderImpl::HandleReadPixels(
6712 uint32 immediate_data_size, const cmds::ReadPixels& c) { 6826 uint32 immediate_data_size, const cmds::ReadPixels& c) {
6713 if (ShouldDeferReads()) 6827 if (ShouldDeferReads())
6714 return error::kDeferCommandUntilLater; 6828 return error::kDeferCommandUntilLater;
6715 GLint x = c.x; 6829 GLint x = c.x;
6716 GLint y = c.y; 6830 GLint y = c.y;
6717 GLsizei width = c.width; 6831 GLsizei width = c.width;
6718 GLsizei height = c.height; 6832 GLsizei height = c.height;
6719 GLenum format = c.format; 6833 GLenum format = c.format;
6720 GLenum type = c.type; 6834 GLenum type = c.type;
6835 GLboolean async = c.async;
6721 if (width < 0 || height < 0) { 6836 if (width < 0 || height < 0) {
6722 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); 6837 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
6723 return error::kNoError; 6838 return error::kNoError;
6724 } 6839 }
6725 typedef cmds::ReadPixels::Result Result; 6840 typedef cmds::ReadPixels::Result Result;
6726 uint32 pixels_size; 6841 uint32 pixels_size;
6727 if (!GLES2Util::ComputeImageDataSizes( 6842 if (!GLES2Util::ComputeImageDataSizes(
6728 width, height, format, type, state_.pack_alignment, &pixels_size, 6843 width, height, format, type, state_.pack_alignment, &pixels_size,
6729 NULL, NULL)) { 6844 NULL, NULL)) {
6730 return error::kOutOfBounds; 6845 return error::kOutOfBounds;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
6810 memset(dst, 0, unpadded_row_size); 6925 memset(dst, 0, unpadded_row_size);
6811 6926
6812 // If the row is in range, copy it. 6927 // If the row is in range, copy it.
6813 if (ry >= 0 && ry < max_size.height() && read_width > 0) { 6928 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
6814 glReadPixels( 6929 glReadPixels(
6815 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); 6930 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6816 } 6931 }
6817 dst += padded_row_size; 6932 dst += padded_row_size;
6818 } 6933 }
6819 } else { 6934 } else {
6935 if (async && features().use_async_readpixels) {
6936 GLuint buffer;
6937 glGenBuffersARB(1, &buffer);
6938 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
6939 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
6940 GLenum error = glGetError();
6941 if (error == GL_NO_ERROR) {
6942 glReadPixels(x, y, width, height, format, type, 0);
6943 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
6944 new FenceCallback()));
6945 WaitForReadPixels(base::Bind(
6946 &GLES2DecoderImpl::FinishReadPixels,
6947 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
6948 <GLES2DecoderImpl>(this),
6949 c, buffer));
6950 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
6951 return error::kNoError;
6952 }
6953 }
6820 glReadPixels(x, y, width, height, format, type, pixels); 6954 glReadPixels(x, y, width, height, format, type, pixels);
6821 } 6955 }
6822 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); 6956 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
6823 if (error == GL_NO_ERROR) { 6957 if (error == GL_NO_ERROR) {
6824 if (result != NULL) { 6958 if (result != NULL) {
6825 *result = true; 6959 *result = true;
6826 } 6960 }
6827 6961 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 } 6962 }
6873 6963
6874 return error::kNoError; 6964 return error::kNoError;
6875 } 6965 }
6876 6966
6877 error::Error GLES2DecoderImpl::HandlePixelStorei( 6967 error::Error GLES2DecoderImpl::HandlePixelStorei(
6878 uint32 immediate_data_size, const cmds::PixelStorei& c) { 6968 uint32 immediate_data_size, const cmds::PixelStorei& c) {
6879 GLenum pname = c.pname; 6969 GLenum pname = c.pname;
6880 GLenum param = c.param; 6970 GLenum param = c.param;
6881 if (!validators_->pixel_store.IsValid(pname)) { 6971 if (!validators_->pixel_store.IsValid(pname)) {
(...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after
9091 bool GLES2DecoderImpl::ProcessPendingQueries() { 9181 bool GLES2DecoderImpl::ProcessPendingQueries() {
9092 if (query_manager_.get() == NULL) { 9182 if (query_manager_.get() == NULL) {
9093 return false; 9183 return false;
9094 } 9184 }
9095 if (!query_manager_->ProcessPendingQueries()) { 9185 if (!query_manager_->ProcessPendingQueries()) {
9096 current_decoder_error_ = error::kOutOfBounds; 9186 current_decoder_error_ = error::kOutOfBounds;
9097 } 9187 }
9098 return query_manager_->HavePendingQueries(); 9188 return query_manager_->HavePendingQueries();
9099 } 9189 }
9100 9190
9191 // Note that if there are no pending readpixels right now,
9192 // this function will call the callback immediately.
9193 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9194 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9195 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9196 } else {
9197 callback.Run();
9198 }
9199 }
9200
9201 void GLES2DecoderImpl::ProcessPendingReadPixels() {
9202 while (!pending_readpixel_fences_.empty() &&
9203 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9204 std::vector<base::Closure> callbacks =
9205 pending_readpixel_fences_.front()->callbacks;
9206 pending_readpixel_fences_.pop();
9207 for (size_t i = 0; i < callbacks.size(); i++) {
9208 callbacks[i].Run();
9209 }
9210 }
9211 }
9212
9101 bool GLES2DecoderImpl::HasMoreIdleWork() { 9213 bool GLES2DecoderImpl::HasMoreIdleWork() {
9102 return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); 9214 return !pending_readpixel_fences_.empty() ||
9215 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
9103 } 9216 }
9104 9217
9105 void GLES2DecoderImpl::PerformIdleWork() { 9218 void GLES2DecoderImpl::PerformIdleWork() {
9219 ProcessPendingReadPixels();
9106 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) 9220 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
9107 return; 9221 return;
9108 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); 9222 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
9109 ProcessFinishedAsyncTransfers(); 9223 ProcessFinishedAsyncTransfers();
9110 } 9224 }
9111 9225
9112 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( 9226 error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
9113 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { 9227 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
9114 GLenum target = static_cast<GLenum>(c.target); 9228 GLenum target = static_cast<GLenum>(c.target);
9115 GLuint client_id = static_cast<GLuint>(c.id); 9229 GLuint client_id = static_cast<GLuint>(c.id);
9116 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); 9230 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9117 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 9231 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9118 9232
9119 switch (target) { 9233 switch (target) {
9120 case GL_COMMANDS_ISSUED_CHROMIUM: 9234 case GL_COMMANDS_ISSUED_CHROMIUM:
9121 case GL_LATENCY_QUERY_CHROMIUM: 9235 case GL_LATENCY_QUERY_CHROMIUM:
9122 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: 9236 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
9237 case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM:
9123 case GL_GET_ERROR_QUERY_CHROMIUM: 9238 case GL_GET_ERROR_QUERY_CHROMIUM:
9124 break; 9239 break;
9125 default: 9240 default:
9126 if (!features().occlusion_query_boolean) { 9241 if (!features().occlusion_query_boolean) {
9127 LOCAL_SET_GL_ERROR( 9242 LOCAL_SET_GL_ERROR(
9128 GL_INVALID_OPERATION, "glBeginQueryEXT", 9243 GL_INVALID_OPERATION, "glBeginQueryEXT",
9129 "not enabled for occlusion queries"); 9244 "not enabled for occlusion queries");
9130 return error::kNoError; 9245 return error::kNoError;
9131 } 9246 }
9132 break; 9247 break;
9133 } 9248 }
9134 9249
9250 // TODO(hubbe): Make it possible to have one query per type running at the
9251 // same time.
9135 if (state_.current_query.get()) { 9252 if (state_.current_query.get()) {
9136 LOCAL_SET_GL_ERROR( 9253 LOCAL_SET_GL_ERROR(
9137 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); 9254 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
9138 return error::kNoError; 9255 return error::kNoError;
9139 } 9256 }
9140 9257
9141 if (client_id == 0) { 9258 if (client_id == 0) {
9142 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); 9259 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
9143 return error::kNoError; 9260 return error::kNoError;
9144 } 9261 }
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
10346 return error::kNoError; 10463 return error::kNoError;
10347 } 10464 }
10348 10465
10349 // Include the auto-generated part of this file. We split this because it means 10466 // 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 10467 // 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. 10468 // instead of having to edit some template or the code generator.
10352 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 10469 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10353 10470
10354 } // namespace gles2 10471 } // namespace gles2
10355 } // namespace gpu 10472 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698